Cod sursa(job #482492)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 3 septembrie 2010 17:36:57
Problema Suma divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.94 kb
#include<fstream>
#include<iostream>
#include<bitset>
#include<vector>
using namespace std;

typedef long long int64;

const unsigned int MOD = 9901;

template<unsigned long numbits>
struct PrimeSieve
{
	long long num;
	bitset<numbits> bits;

	void GeneratePrimes(const long long n)
	{
		num=1;
		for(int i=1; ((i<<1)+1)*((i<<1)+1)<n; ++i)
		{
			if(!bits[i])
			{
				for(long long j=i; ((i<<1)+1)*((j<<1)+1)<n; ++j)
				{
					const long long index=((i<<1)+1)*((j<<1)+1);
					bits[index>>1]=1;
				}
			}
		}
	}
	
	const bitset<numbits>& GetPrimes() const
	{
		return bits;
	}
};

int64 powl(int64 n, int p)
{
	int64 rez=1;
	while(p)
	{
		if(p&1)
		{
			rez=(rez*n)%MOD;
		}
		n=(n*n)%MOD;
		p>>=1;
	}
	return rez;
}

void Decompose(int64& n, int64 div, int64& p, int64& d)
{
	d=p=0;
	if(n % div == 0)
	{
		p=div;
		while(n % div == 0)
		{
			d++;
			n/=div;
		}
	}
}

int main()
{
	int64 n,p,d,pow;
	fstream fin("sumdiv.in", fstream::in);
	fstream fout("sumdiv.out", fstream::out);
	vector<unsigned long> v;
	
	PrimeSieve<500007> primes;
	primes.GeneratePrimes(500005);
	v.push_back(2);
	for(int i=1; i<500005; ++i)
		if(!(primes.GetPrimes())[i])
			v.push_back((i<<1)+1);
	
	fin>>n>>pow;
	//cout<<n<<" ~ "<<pow<<endl;
	
	int64 i=0,s=1;
	while(n>1 && v[i]*v[i]<=n)
	{
		Decompose(n, v[i], p, d);
		if(p)
		{
			d*=pow;
			int64 power=(powl(p, d+1)-1)%MOD;
			if(power<0)
				power+=MOD;
			int64 divi=powl(p-1, MOD-2)%MOD;
			if(divi < 0)
				divi+=MOD;
			s=( ((s*power)%MOD)*divi)%MOD;
		}
		i++;
	}
	if(n!=1)
	{
		if(n%MOD > 1)
		{
			p=n;
			d=pow;
			int64 power=(powl(p, d+1)-1)%MOD;
			if(power<0)
				power+=MOD;
			int64 divi=powl(p-1, MOD-2)%MOD;
			if(divi < 0)
				divi+=MOD;
			s=( ((s*power)%MOD)*divi)%MOD;
		}
		else if (n%MOD==1)
			s=s*(pow%MOD+1)%MOD;
	}

	fout<<s<<endl;
	//cout<<s<<"\n";
	
	fin.close();
	fout.close();
	return 0;
}