Cod sursa(job #1125875)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 26 februarie 2014 19:57:25
Problema Suma si numarul divizorilor Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.81 kb
#include <iostream>
#include <fstream>
#include <bitset>

using namespace std;

const int MOD = 9973;
const int Nmax = 1000000;

int P;
bitset <Nmax> ciur;
int Primes[80000];

void gen()
{
    for ( int i = 2; i < Nmax; i++ )
            ciur[i] = 1;

    for ( int i = 4; i < Nmax; i += 2 )
            ciur[i] = 0;

    Primes[ ++P ] = 2;

    for ( int i = 3; i < Nmax; i += 2 )
            if ( ciur[i] )
            {
                Primes[ ++P] = i;

                for ( int j = 3 * i; j < Nmax; j += 2 * i )
                        ciur[j] = 0;
            }
}

int pw( int a, int p )
{
    int res = 1;

    for ( int i = 0; ( 1 << i ) <= p; ++i )
    {
        if ( p & ( 1 << i ) )
                res = ( res * a ) % MOD;

        a = ( a * a ) % MOD;
    }

    return res;
}

int inv( int a )
{
    return pw( a, MOD - 2 );
}

void solve( long long n, ostream &f )
{
    long long nr_div = 1;
    long long sum_div = 1;

    for ( int i = 1; i <= P && Primes[i] * Primes[i] <= n; ++i )
    {
        if ( n % Primes[i] ) continue;

        int e = 0;

        while ( n % Primes[i] == 0 )
        {
            e++;
            n /= Primes[i];
        }

        nr_div = ( nr_div * ( e + 1 ) ) % MOD;
        sum_div = ( ( sum_div * ( pw( Primes[i], e + 1 ) - 1 + MOD ) % MOD ) * inv( Primes[i] - 1 ) % MOD ) % MOD;

    }

    if ( n > 1 )
    {
        nr_div = ( nr_div * 2 ) % MOD;
        sum_div = ( ( sum_div * ( pw( n, 2 ) - 1 + MOD ) % MOD ) * inv( n - 1 ) % MOD ) % MOD;
    }

    f << nr_div << " " << sum_div << "\n";
}

long long N;
int T;

int main()
{
    gen();

    ifstream f("ssnd.in");
    ofstream g("ssnd.out");

    f >> T;

    while ( T-- )
    {
        f >> N;

        solve( N, g );
    }

    return 0;
}