Cod sursa(job #1213249)

Utilizator acomAndrei Comaneci acom Data 27 iulie 2014 17:35:06
Problema Suma si numarul divizorilor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.25 kb
#include<fstream>
#include<bitset>
using namespace std;
#define NMAX 1000005
#define MOD 9973
ifstream fin("ssnd.in");
ofstream fout("ssnd.out");
bitset <NMAX> p;
int t,k,nmax,a[NMAX>>3];
long long n,v[NMAX>>3];
void ciur()
{
    int i,j;
    p[1]=1;
    for (i=2;i<NMAX;++i)
        if (!p[i])
        {
            v[++k]=i;
            for (j=2;i*j<NMAX;++j)
                p[i*j]=1;
        }
}
long long power(long long n, long long p)
{
    long sol=1;
    while (p)
    {
        if (p&1) sol*=n, sol%=MOD;
        n*=n, n%=MOD;
        p>>=1;
    }
    return sol;
}
int cb(long long n)
{
    int st,dr,mij;
    st=1, dr=k;
    while (st<=dr)
    {
        mij=st+((dr-st)>>1);
        if (v[mij]==n)
            return mij;
        if (v[mij]<n)
            st=mij+1;
        else
            dr=mij-1;
    }
    return 0;
}
void descomp()
{
    int i,aux;
    nmax=0;
    for (i=1;v[i]*v[i]<=n && i<=k;++i)
    {
        a[i]=0;
        while (n%v[i]==0)
        {
            if (i>nmax) nmax=i;
            ++a[i];
            n/=v[i];
        }
    }
    if (n>1)
    {
        aux=cb(n);
        a[aux]=1;
        for (i=nmax+1;i<aux;++i)
            a[i]=0;
        if (nmax<aux) nmax=aux;
    }
}
long long cmmdc(long long a, long long b, long long &x, long long &y)
{
    if (b==0)
    {
        x=1, y=0;
        return a;
    }
    else
    {
        long long x0,y0,d=cmmdc(b,a%b,x0,y0);
        x=y0, y=x0-(a/b)*y0;
        return d;
    }
}
long long nrdiv()
{
    int i,nr=1;
    for (i=1;i<=nmax;++i)
        if (a[i])
            nr*=1+a[i], nr%=MOD;
    return nr;
}
long long sumdiv()
{
    int i,nr=1,aux;
    long long x,y;
    for (i=1;i<=nmax;++i)
        if (a[i])
        {
            cmmdc(v[i]-1,MOD,x,y);
            x%=MOD;
            if (x<0) x+=MOD;
            aux=power(v[i],a[i]+1), --aux;
            nr*=(x*aux)%MOD, nr%=MOD;
            if (nr<0) nr+=MOD;
        }
    return nr;
}
int main()
{
    int i;
    freopen("ssnd.in","r",stdin);
    freopen("ssnd.out","w",stdout);
    ciur();
    fin>>t;
    for (i=0;i<t;++i)
    {
        fin>>n;
        descomp();
        fout<<nrdiv()<<" "<<sumdiv()<<"\n";
    }
    return 0;
}