Cod sursa(job #801826)

Utilizator lucian666Vasilut Lucian lucian666 Data 24 octombrie 2012 23:28:20
Problema Suma divizorilor Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.78 kb


//Vasilut
#include<fstream>
#include<bitset>

#define NN 1000010
#define Mod 9901

using namespace std;
ofstream out("sumdiv.out");
ifstream in("sumdiv.in");

long long x,y;
int T,m,prim[NN];
bitset<NN>uz;

void ciur();
void read();
void solve();
int make_power(int baza,long long int expo); // pt a calcula a la puterea b

int main()
{
    ciur();
    read();
    return 0;
}

void read()
{


    in>>x>>y;
    solve();
}

void ciur()
{
    for(int i=2;i<NN ;++i) // parcurgem toate nr de la 2 la n
        if (!uz[i] ) // este prim
        {
            prim[ ++m ]= i; // il adaugam in vectorul de nr prime
                for(int j= ( i << 1) ; j<NN; j+=i) // parcurgem toti multiplii lui i
                    uz[j]=1; //ii marcam ca nefiind nr prime
        }
}


inline int make_power(int baza,long long int expo)
{
    int rez=1;
    baza %= Mod;

    for( ; expo ; expo >>= 1 ) //atat timp cat exponentul e pozitiv ,il impartim la 2
    {
        if( expo & 1 ) // daca e par
        {
            rez=1LL * rez* baza;
            rez%=Mod;
        }
        baza =1LL * baza * baza;
        baza %=Mod;
    }
    return rez;
}


/* cu ridicarea de mai jos iau doar 70 pct ,cu 3 incorect :D

inline int make_power(int baza,int expo)
{
    int i;
    int b[50],nrb=0;
    for( ; expo ; expo >>= 1 )
        b[++nrb]= expo % 2;
    int rez=1;
    for( i = nrb ; i ; --i )
    {
        rez=( rez * rez ) % Mod;
                if ( b[i] )
                    rez= ( rez * baza ) % Mod;
    }
    return rez;
}

*/

void solve()
{

    long long n=make_power(x,y);
    int nd,sd; // nr de divizori ,suma divizorilor
    nd=1,sd=1; // le dam 1
    for(int i=1; i <= m  && 1LL * prim[i] * prim[i] <=n ;++i) // parcurgem nr prime doar pana la radical din n,in vectorul prim avand memorate factorii primi
    {
        if( n % prim[i] ) //nu e factor prim
        continue;

        int p=0;
        while ( n % prim[i] == 0 )
        {
            n/=prim[i];
            ++p; // puterea la care apare factorul prim[i] in descompunerea lui n
        }

        nd*=(p+1); // calculam nr de divizori cu formula nd=(p1+1) * (p2 +1 ) * ....(pk +1 ),unde k e ultimul divizor prim din descompunerea lui n

        int p1,p2; //calculam suma cu formula sd=(prim[i]^(p+1 ) -1 / prim[i] -1 ) * (prim[i+1] * (p2 + 1) -1 /prim[i+1] -1 ) * .... unde prim[i] e fact din desc lui n,iar p e puterea la care apare
        p1= ( make_power(prim[i],p+1) -1 ) % Mod;
        p2= make_power(prim[i] -1,Mod-2)  % Mod;// intorc fractia din formula

        sd= ( ( ( sd * p1 ) % Mod ) * p2 ) % Mod;
    }
    if( n > 1)
    {
        nd *=2;
        sd=( 1LL *sd * (n+1 ) % Mod );
    }

    out<<sd<<" "<<'\n';
}