Cod sursa(job #442471)

Utilizator nandoLicker Nandor nando Data 14 aprilie 2010 17:01:20
Problema Suma si numarul divizorilor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.37 kb
#include <cstdio>
#include <bitset>
using namespace std;

FILE* fin=fopen("sumdiv.in","r");
FILE* fout=fopen("sumdiv.out","w");

#define MAX 7500
#define MOD 9901

typedef long long int64;
bitset<MAX> p;
int64 prim[1000],np=0;

void ciur(){
	for(int i=1;((i*i)<<1)+(i<<1)<MAX;++i){
		if(!p[i]){
			for(int j=((i*i)<<1)+(i<<1);(j<<1)+1<MAX;j+=(i<<1)+1){
				p[j]=true;
			}
		}
	}
	prim[np++]=2;
	for(int i=1;(i<<1)+1<MAX;++i){
		if(!p[i]){
			prim[np++]=(i<<1)+1;
		}
	}
}

void euclid(int64 a,int64 b,int64& x,int64& y){
	if(b==0){
		x=1,y=0;
	}else{
		int64 x0,y0;
		euclid(b,a%b,x0,y0);
		x=y0;
		y=x0-(a/b)*y0;
	}
}

int invMod(int a){
	int64 x,y;
	euclid(a,MOD,x,y);
	while(x<0)
		x+=MOD;
	return x;
}

int64 pow(int64 a,int64 b){
	int64 x=a%MOD,r=1;
	while(b){
		if(b&1){
			r=(r*x)%MOD;
		}
		x=(x*x)%MOD;
		b>>=1;
	}
	return r;
}

int main(){
	ciur();

	int64 a,b,k,sd=1;
	fscanf(fin,"%lld %lld\n",&a,&b);	
	
	k=a;
	for(int i=0;prim[i]*prim[i]<=a;i++){
		if(a%prim[i]==0){
			int64 p=0,s=1;
			while(k%prim[i]==0){
				p++,s*=prim[i],k/=prim[i];
			}
			s=(pow(s,b)*prim[i])%MOD;
			sd=(sd*(((s-1)%MOD))*invMod(prim[i]-1))%MOD;
		}
	}
	if(k>1){
		if(k%MOD!=1){
			sd=(sd*(((pow(k,b+1)-1)%MOD))*invMod(k-1))%MOD;
		}
	}
	getchar();
	fprintf(fout,"%lld\n",sd);
	fclose(fin);
	fclose(fout);
	return 0;
}