Cod sursa(job #48488)

Utilizator butyGeorge Butnaru buty Data 4 aprilie 2007 20:25:59
Problema Suma divizorilor Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.69 kb
#include<stdio.h>
#include<assert.h>
#include<math.h>
int A,B,pr[2048],P[2048],E[2048],nrp,nrA;
int sieve[10001],SumDiv;
void cit()
{
    freopen("sumdiv.in","r",stdin);
    scanf("%d%d",&A,&B);
    
}
void prime()
{
    int i,j;
    pr[++nrp]=2;
    for(i=3;i<=10000;i+=2)
    {
        if(sieve[i]) continue;
        pr[++nrp]=i;
        for(j=i*i;j<=10000;j+=2*i)
            sieve[j]=1;
    }
}
void div(int &X,int y,int k)
{
    if(X%y==0&&X)
    {
        X/=y;
        E[nrA]+=k;
        div(X,y*y,2*k);
    }
    else
        if(y>P[nrA]&&X)
            div(X,(int)sqrt(y),k/2);
}
int invmod (int x) 
{     
	 int p = 9901 - 2, rv = 1, oldx = x;    
	 for (; p; p /= 2)
	 {      
		 rv = p & 1 ? x * rv % 9901 : rv;  
     	 x = x*x % 9901; 
	 }   
   assert ((rv * oldx % 9901) == 1);
  return rv;
}
int putere(int a,int b)
{
    if(b==1) return a;
    if(b%2)
        return (a*putere((a*a)%9901,(b-1)/2))%9901;
    else
        return putere((a*a)%9901,b/2);
}
void rez()
{
    int i,x,s,j;
    //divizorii lui A
    prime();
    for(i=1;i<=nrp;i++)
        if(A%pr[i]==0)
        {
            ++nrA;
            P[nrA]=pr[i];
            //div(A,P[nrA],1); log2 E[nrA]...
            while(A%P[nrA]==0&&A)
            {
                A/=P[nrA];
                E[nrA]++;
            }
        }
    nrp=nrp;
    SumDiv=1;
    for(i=1;i<=nrA;i++)
    {
        s=putere(P[i],E[i]*B+1);
        SumDiv*=((s-1)*invmod(P[i]-1))%9901;
        SumDiv%=9901;
    }
}
void scr()
{
    freopen("sumdiv.out","w",stdout);
    printf("%d\n",SumDiv);
    fclose(stdout);
}
int main()
{
    cit();
    rez();
    scr();
    return 0;
}