Cod sursa(job #394094)

Utilizator AndreyPAndrei Poenaru AndreyP Data 10 februarie 2010 15:37:52
Problema Suma divizorilor Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.09 kb
#include<stdio.h>
#include<stdlib.h>
#define M 9901
int a,b;
int np;
int p[10];
int e[10];
int d[1024];
int rez;
inline int put(int b,int e)
{
	int r=1;
	b%=M;
	for(; e>0; e>>=1)
	{
		if((e&1)==1)
			r=(r*b)%M;
		b=(b*b)%M;
	}
	return r;
}
int main()
{
	freopen("sumdiv.in","r",stdin);
	freopen("sumdiv.out","w",stdout);

	scanf("%d%d",&a,&b);
	if(a==0)
		exit(4);
	if(b==0)
	{
		printf("1\n");
		return 0;
	}
        if((a&1)==0)
	{
		np=1;
		p[0]=2;
		while((a&1)==0)
		{
			a>>=1;
			++e[0];
		}
		e[0]*=b;
	}
        for(int i=3; i*i<=a; i+=2)
	{
		if(a%i==0)
		{
			p[np]=i;
			while(a%i==0)
			{
				++e[np];
				a/=i;
			}
			e[np]*=b;
			++np;
		}
	}
	if(a!=1)
	{
		p[np]=a;
		e[np]=b;
		++np;
	}
	
	d[0]=1;
	int lim=1<<np;
	int aux;
        for(int i=1,j,cat; i<lim; ++i)
	{
		for(j=0,cat=1; (i&cat)==0; ++j,cat<<=1)
			;
		if(j>=np)
			exit(4);
		aux=put(p[j],e[j]);
		if(aux==0)
			aux=M-1;
		else
			--aux;
                d[i]=(((((d[(i^cat)]*(p[j]%M))%M)*aux)%M)*put(p[j]-1,M-2))%M;
	}
        rez=1;
	for(int i=1; i<lim; ++i)
	{
		rez+=d[i];
		if(rez>=M)
			rez-=M;
	}
	printf("%d\n",rez);
	return 0;
}