Cod sursa(job #1670196)

Utilizator CrystyAngelDinu Cristian CrystyAngel Data 31 martie 2016 15:45:44
Problema Ridicare la putere in timp logaritmic Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.52 kb
#include <cstdio>
#include <cmath>
#include <bitset>
using namespace std;

FILE *f=fopen("ssnd.in","r");
FILE *g=fopen("ssnd.out","w");
#define ll long long
#define fs(n) fscanf(f,"%lld",&n)
#define fp fprintf
inline ll po(ll a,ll b)
{
    if(b==1)
        return a%9973;
    else
    if(b%2==0)
        return po((a*a)%9973,b/2);
    return (a*po(a,b-1))%9973;
}
struct nod
{
    int f,p;
}v[100];
#define nmax 1000010

bitset <nmax/2+1> p;
int prim[nmax/4];
int i,j,m,z;
long long x,s,nr,n;

int main()
{
    prim[0]=2;x=nmax;
    for(i=1; (((i*i)<<1)+(i<<1))<=x; ++i)
    {
        if(!p[i])
        {
            for(j=(((i*i)<<1)+(i<<1)) ; (j<<1) <=x; j+= (i<<1) +1 )
                p[j]=1;
        }
    }
    m=0;
    for(i=1; (i<<1)+1<nmax; ++i)
        if(!p[i])
            prim[++m]=(i<<1)+1;
    fs(n);
    for(i=1;i<=n;i++)
    {
        fs(x);
        z=0;
        for( j=0; j<=m && x>1; ++j)
        if(x%prim[j]==0)
        {
            v[z].f=prim[j];
            v[z++].p=1;
            x/=prim[j];
            while(x%prim[j]==0)
            {
                v[z-1].p++;
                x/=prim[j];
            }
        }
        if(x!=1)
            {
                v[z].f=x;
                v[z++].p=1;
            }
        nr=1;
        s=1;
        for( j=0; j<z; ++j)
        {
            nr*=v[j].p+1;
            s*=po(v[j].f,v[j].p+1)-1;
            s/=(v[j].f-1);
            s%=9973;
        }
        fp(g,"%lld %lld\n",nr,s);
    }
}