Cod sursa(job #1213936)

Utilizator Adrian1997Radulescu Adrian Adrian1997 Data 29 iulie 2014 11:38:52
Problema Suma si numarul divizorilor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
#include <fstream>
#include <list>
#include <cmath>
#define DIM 1000000
#define MOD 9973
using namespace std;
ifstream f("ssnd.in");
ofstream g("ssnd.out");
int n;
bool viz[DIM+11];

list<int> P;
list<int>::iterator it;

void eratostenes(){
    for(register int i=2;i<DIM;i++)
        if(viz[i]==0){
            P.push_back(i);
            for(register int j=i+i;j<DIM;j+=i) viz[j]=true;
        }
}

inline int nrdiv(int x){
    int nr=1,q;
    for(it=P.begin();it!=P.end() && x!=1;it++){
        if(*it>sqrt(x))
            break;
        q=0;
        while(x%(*it)==0)
            x/=(*it),q++;
        nr*=(q+1);
    }
    if(x!=1) nr*=2;
    return nr;
}

inline int p(int a,int &b){
    int nr=0;
    while(b%a==0)
        nr++,b/=a;
    return nr;
}

inline int up(int a,int b){
    int q=1;
    for(;b;b--)
        q*=a,q%=MOD;
    return q;
}

inline int cmmdc(int a,int b,int &x,int &y){
    if(!b){
        x=1,y=0;
        return a;
    }
    else{
        int xa,ya,d=cmmdc(b,a%b,xa,ya);
        x=ya;
        y=xa-(a/b)*ya;
        return d;
    }
}

inline int invmod(int a){
    int b,d,x,y;
    d=cmmdc(a,MOD,x,y);
    x = x%MOD;
    if (x < 0)
        x += MOD;
    return x;
}

inline int sumdiv(int x){
    int sum=1,a,b;
    for(it=P.begin();it!=P.end();it++){
        if(*it>sqrt(x))
            break;
        b=p(*it,x);
        a=up(*it,b+1)-1;
        if(a<0)
            a+=MOD;
        b=invmod(*it-1);
        sum*=(a*b)%MOD,sum%=MOD;
    }
    if(x!=1){
        sum*=(x+1);
    }
    return sum%MOD;
}

int main(void){
    register int i,j,t;

    eratostenes();

    f>>t;
    for(;t;t--){
        f>>n;
        g<<nrdiv(n)<<" "<<sumdiv(n)<<"\n";
    }
    f.close();
    g.close();
    return 0;
}