Cod sursa(job #993359)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 3 septembrie 2013 18:09:04
Problema Suma si numarul divizorilor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 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;

unsigned long long llpow(unsigned long long a, unsigned long long b){
    if(b==0) return 1;
    else if(b==1) return a;
    else{
        unsigned long long x=llpow(a,b/2);
        if(b%2==0) return x*x;
        else return a*x*x;
    }

}

void calc_primes(vector<unsigned> &primes,vector<bool> &ciur,unsigned limit){
    primes[0]=2;
    unsigned c=1;
    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;
        }
}

inline bool isprime(unsigned n, const vector<bool> &ciur){
    if(n==2) return true;
    else return (n&1) && ciur[n>>1];
}

int main(){
    std::ifstream fin("ssnd.in");
    std::ofstream fout("ssnd.out");

    short t;
    fin>>t;

    vector<unsigned> primes(NR_PRIMES_BELOW_ONE_MILION);
    vector<bool> ciur(500000,true);
    calc_primes(primes,ciur,1000000);

    while(t--){
        unsigned n; fin>>n;
        unsigned sqrtn=std::sqrt(n);
        unsigned long long nrdiv=1,sumdiv=1;

        for(unsigned i=0;primes[i]<=sqrtn&&n>1;++i){
            unsigned long long p=primes[i];
            if(n%p==0){
                unsigned d=0;
                while(n%p==0){ ++d; n/=p; }
                nrdiv=(nrdiv*(d+1))%MODULO;
                sumdiv=( sumdiv * (llpow(p,d+1)-1) / (p-1) )%MODULO;
            }
        }

        if(n>1){ nrdiv=(nrdiv*2)%MODULO; sumdiv=( sumdiv * (llpow(n,2)-1) / (n-1) )%MODULO; }
        fout<<nrdiv<<' '<<sumdiv<<'\n';
    }
}