Cod sursa(job #2823636)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 29 decembrie 2021 09:49:25
Problema Suma si numarul divizorilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.14 kb
#include <fstream>

#include <vector>

#include <cmath>

using std::vector;

using std::sqrt;



const int NR_PRIMES_BELOW_ONE_MILION=78498;

const int MODULO=9973;



void euclid_extins(int *x,int *y,int a, int b){

    if(b==0){ *x=1; *y=0; }

    else{

        int x0,y0,c=a/b;

        euclid_extins(&x0,&y0,b,a%b);

        *x=y0;

        *y=x0-c*y0;

    }

}



unsigned getmodinv(unsigned a){

    int x,y;

    euclid_extins(&x,&y,a,MODULO);

    while(x<0) x+=MODULO;

    return x;

}



unsigned modexp(unsigned long long base, unsigned exp){

    if(exp==0) return 1;

    else if(exp==1) return base%MODULO;

    else{

        unsigned x=modexp(base,exp>>1);

        if(exp&1) return ((base%MODULO)*x*x)%MODULO;

        else return x*x%MODULO;

    }

}



void addf(unsigned *nrdiv,unsigned *sumdiv,unsigned long long p,unsigned d,const vector<unsigned> &modinvs){

    *nrdiv = (*nrdiv) * (d+1) % MODULO;

    unsigned me=modexp(p,d+1);

    if(me==0) me=MODULO-1;

    else --me;

    unsigned k = me * modinvs[(p-1)%MODULO] %MODULO;

    *sumdiv = *sumdiv * k %MODULO;

}



void calc_primes(vector<unsigned> &primes,unsigned limit){

    primes[0]=2;

    unsigned c=1;

    vector<bool> ciur(500000,true);

    ciur[0]=false;

    for(unsigned i=3;i<limit;i+=2)

        if(ciur[i>>1]){

            primes[c++]=i;

            for(unsigned j=3;j*i<limit;j+=2) ciur[(i*j)>>1]=false;

        }

}



int main(){

    std::ifstream fin("ssnd.in");

    std::ofstream fout("ssnd.out");



    short t;

    fin>>t;

    vector<unsigned> primes(NR_PRIMES_BELOW_ONE_MILION);

    calc_primes(primes,1000000);



    vector<unsigned> modinvs(MODULO);

    modinvs[0]=0;

    for(unsigned i=1;i<MODULO;i++) modinvs[i]=getmodinv(i);



    while(t--){

        unsigned long long n; fin>>n;

        unsigned nrdiv=1,sumdiv=1;



        unsigned long long p=primes[0];

        for(unsigned i=0;p*p<=n;++i){

            unsigned d=0;

            while(n%p==0){ ++d; n/=p; }

            if(d>0) addf(&nrdiv,&sumdiv,p,d,modinvs);

            p=primes[i+1];

        }

        if(n>1) addf(&nrdiv,&sumdiv,n,1,modinvs);



        fout<<nrdiv<<' '<<sumdiv<<'\n';

    }

}