Cod sursa(job #718089)

Utilizator algotrollNume Fals algotroll Data 20 martie 2012 15:13:07
Problema Suma si numarul divizorilor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.83 kb
#include<cstdio>
#include<cmath>
#include<vector>
#define _CIURMAX 1000010
#define MOD 9973
typedef unsigned long long ull;
void double_assign (int &l1, int &l2, int r1, int r2)
{
    l1=r1; l2=r2;
}

std::vector<int> lPrime;
void ciuruieste()
{
    static bool compus[_CIURMAX];
    for (int i=3;i<sqrt(_CIURMAX);i+=2)
        if (!compus[i])
            for (int k=i*i;k<_CIURMAX;k+=i)
                compus[k]=1;
    lPrime.reserve(_CIURMAX);
    for (int i=3;i<_CIURMAX;i+=2)
        if (!compus[i]) lPrime.push_back(i);
}

int pow(int base, int exp)
{
    if (exp==1) return base %MOD;
    if (exp%2==0) return pow(base,exp/2)*pow(base,exp/2);
    else return (ull) pow(base,exp/2)*pow(base,exp/2)*base %MOD;
}

int inv_mod(int D, int I)
{
    //D = Ix (mod B)
    //Ix +By = 1 -> I*Dx+B*Dy = D
    int a=I, b=MOD;
    int prevx=1,prevy=0,x=0,y=1;
    while (b!=0)
    {
        int cat = a/b;
        double_assign(prevx,x   ,x,prevx-cat*x);
        double_assign(prevy,y   ,y,prevy-cat*y);
        double_assign(a,b    ,b,a%b);

    }
    if (prevx<0) prevx=prevx%MOD +MOD;
    return prevx*D %MOD;
}

void print_nr_sum(int);
int main()
{
    ciuruieste();
    freopen("ssnd.in","r",stdin);
    freopen("ssnd.out","w",stdout);
    int nNr; scanf("%d", &nNr);
    for (int i=1;i<=nNr;i++)
    {
        int n; scanf("%d",&n);
        print_nr_sum(n);
    }
    return 0;
}

void print_nr_sum(int n)
{
    int nDiv, sum;
    int exp=0;
    for (;n%2==0;n/=2) exp++;
    nDiv=(exp+1);
    sum=pow(2,exp+1)-1;
    for (std::vector<int>::iterator pPr=lPrime.begin(); *pPr<=n; ++pPr)
    {
        if (n%*pPr!=0) continue;
        exp=0;
        for (;n%*pPr==0;n/=*pPr) exp++;
        nDiv*=(exp+1);
        sum*=inv_mod(pow(*pPr,exp+1)-1,*pPr-1) %MOD;
    }
    printf("%d %d\n",nDiv,sum);
}