Cod sursa(job #978741)

Utilizator andrettiAndretti Naiden andretti Data 29 iulie 2013 16:26:34
Problema Suma si numarul divizorilor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.89 kb
#include<stdio.h>
#include<math.h>
#include<cstring>
#define maxd 1000005
#define maxp 80000
#define mod 9973
using namespace std;
typedef long long ll;

int t,p,n,nrd,sum;
int prime[maxp];
bool sieve[maxd];

void preproc()
{
    int i,lim=maxd-5;
    prime[++p]=2;
    for(i=3;i*i<=lim;i+=2)
      if(!sieve[i])
      {
          prime[++p]=i;
          for(int j=i;i*j<=lim;j++)
           sieve[i*j]=true;
      }
    for(;i<=lim;i+=2)
     if(!sieve[i])
      prime[++p]=i;
}

void gcd(int a,int b,int &x,int &y)
{
    if(b==0) {x=1; y=0; return;}
    int x0,y0;
    gcd(b,a%b,x0,y0);
    x=y0%mod;
    y=(x0-(a/b)*y0)%mod;
}

int modular(int a,int b)
{
    int x,y;
    gcd(a,b,x,y);
    while(x<0) x+=mod;
    return x;
}

void update(int nr,int prod,int x)
{
    nrd*=(nr+1);
    sum=(sum*((prod-1)%mod))%mod;
    sum=(sum*x)%mod;
}

int up(int a,int b)
{
    int add=a,sol=1;
    for(int i=0;b>>i;i++)
    {
        if( ((b>>i)&1) )
           sol=((sol%mod)*(add%mod))%mod;
        add=((add%mod)*(add%mod))%mod;
    }
    return sol;
}

void solve()
{
    int nr,prod,inv;
    ll sq;

    scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        scanf("%lld",&n);
        sq=sqrt(n); nrd=1; sum=1;

        for(int j=1;prime[j]<=sq;j++)
         if(n%prime[j]==0)
         {
             inv=modular(prime[j]-1,mod);
             nr=0; while(n%prime[j]==0) nr++,n/=prime[j];

             prod=up(prime[j],nr+1);
             update(nr,prod,inv);
         }

        if(n>1)
        {
            inv=modular(n-1,mod);
            prod=( (n%mod)*(n%mod) )%mod;
            update(1,prod,inv);
        }

        printf("%d %d\n",nrd,sum);
    }
}

int main()
{
    freopen("ssnd.in","r",stdin);
    freopen("ssnd.out","w",stdout);

    preproc();
    solve();

    fclose(stdin);
    fclose(stdout);
    return 0;
}