Cod sursa(job #424010)

Utilizator alexandru92alexandru alexandru92 Data 24 martie 2010 15:41:38
Problema Suma si numarul divizorilor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.99 kb
/* 
 * File:   main.cpp
 * Author: virtualdemon
 *
 * Created on March 24, 2010, 3:05 PM
 */
#include <vector>
#include <cstdlib>
#include <fstream>
#define Modulo  9973
#define NMax 1000003


/*
 *
 */
using namespace std;
char is_prime[ 62510 ];
vector< int > Prime;
void Sieve( void )
{
    int i, j, pas;
    for( i=1; ( (i*i)<<1 ) + (i<<1) < NMax; ++i )
        if( 0 == ( is_prime[i>>3] & ( 1<<(i&7) ) ) )
        {
            pas=(i<<1)+1;
            for( j=( (i*i)<<1 ) + (i<<1); (j<<1) < NMax; j+=pas )
                is_prime[j>>3]|=(1<<(j&7));
        }
    Prime.push_back( 2 );
    for( i=3; i <= NMax; i+=2 )
    {
        j=(i-1)>>1;
        if( 0 == ( is_prime[j>>3] & ( 1<<(j&7) ) ) )
            Prime.push_back( i );
    }
}
inline int pow( int x, int N )
{
    int r=1;
    for( ; N; N>>=1 )
    {
        if( N&1 )
        {
            r=(1LL*r*x)%Modulo;
            --N;
        }
        x=(1LL*x*x)%Modulo;
    }
    return r;
}
int main( void )
{
    Sieve();
    long long int N;
    int T, i, p, d, nrdiv, sdiv;
    ifstream in( "ssnd.in" );
    ofstream out( "ssnd.out" );
    in>>T;
    for( ; T; --T )
    {
        in>>N;
        if( 2 == N )
        {
            out<<"2 3\n";
            continue;
        }
        if( N <= 1000000 &&  N%2 )
        {
            i=(N-1)>>1;
            if( 0 == ( is_prime[i>>3] & (1<<(i&7) ) ) )
            {
                out<<"2 "<<(1+N)<<'\n';
                continue;
            }
        }
        nrdiv=sdiv=1;
        for( i=0; 1LL*Prime[i]*Prime[i] <= N; ++i )
            if( 0 == N%Prime[i] )
            {
                for( p=Prime[i], d=0; 0 == N%p; ++d, N/=p );
                nrdiv=( 1LL*nrdiv*( d+1 ) )%Modulo;
                sdiv=( 1LL * sdiv * ( pow( p, d+1 ) -1 ) * pow( p-1, Modulo-2 )  )%Modulo;
            }
        if( N > 1 )
        {
            nrdiv=( nrdiv*2 )%Modulo;
            sdiv=( 1LL * sdiv * ( N * N -1 ) * pow( N-1, Modulo-2 ) )%Modulo;
        }
        out<<nrdiv<<' '<<sdiv<<'\n';
    }
    return EXIT_SUCCESS;
}