Cod sursa(job #1560196)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 1 ianuarie 2016 22:11:58
Problema Suma divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.83 kb
#include <bits/stdc++.h>

using namespace std;

const int MAX_DIV = 9;
const int MOD = 9901;
const int PHI = MOD - 1;

int divisors[MAX_DIV];
int exponent[MAX_DIV];

inline int lgPut( int base, int exponent )
{
    int q = 1;

    while ( exponent )
    {
        if ( exponent & 1 )
            q = ( 1LL * q * base ) % MOD;

        base = ( 1LL * base * base ) % MOD;
        exponent >>= 1;
    }
    return q;
}

int main()
{
    ifstream in("sumdiv.in");
    ofstream out("sumdiv.out");
    int A, exp;
    int numDiv;

    in >> A >> exp;
    in.close();

    numDiv = 0;

    if ( ( A & 1 ) == 0 )
    {
        divisors[numDiv] = 2;
        exponent[numDiv] = 31 - __builtin_clz( A & -A );
        numDiv++;
        A /= ( A & -A );
    }

    for ( int i = 3; 1LL * i * i <= A; i += 2 )
    {
        if ( A == A / i * i )
        {
            divisors[numDiv] = i;
            exponent[numDiv] = 0;

            do
            {
                exponent[numDiv]++;
                A /= i;
            } while ( A == A / i * i );

            numDiv++;
        }
    }

    if ( A > 1 )
    {
        exponent[numDiv] = 1;
        divisors[numDiv] = A;
        numDiv++;
    }

    for ( int i = 0; i < numDiv; ++i )
        exponent[i] = ( exponent[i] * exp );

    int answer = 1;

    for ( int i = 0; i < numDiv; ++i )
    {
        if ( divisors[i] == 1 + divisors[i] / MOD * MOD )
        {
            answer = ( answer * ( exponent[i] + 1 ) ) % MOD;
            continue;
        }

        int numarator = ( lgPut( divisors[i], ( exponent[i] + 1 ) % PHI ) - 1 + MOD ) % MOD;
        int numitor = lgPut( divisors[i] - 1, PHI - 1 );
        answer = ( 1LL * answer * numarator * numitor ) % MOD;
    }

    out << answer << '\n';
    out.close();
    return 0;
}