Cod sursa(job #793424)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 2 octombrie 2012 21:47:11
Problema Suma divizorilor Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.16 kb

#include <cstdio>

const int MOD(9901);
const int MAX_SIZE(32);

unsigned long long primes [MAX_SIZE];
unsigned long long powers [MAX_SIZE];
unsigned long long a, b, result(1);

inline void read (void)
{
	std::scanf("%llu%llu",&a,&b);
	std::fclose(stdin);
}

inline void print (void)
{
	std::printf("%llu\n",result);
	std::fclose(stdout);
}

inline float sqrt (float x)
{
	static const float MAGIC(0.25f);
	union
	{
		int i;
		float f;
	} u;
	u.f = x;
	u.i = (1 << 29) + (u.i >> 1) - (1 << 22);
	u.f = u.f + x / u.f;
	u.f = MAGIC * u.f + x / u.f;
	return u.f;
}

inline void primes_decomposition (void)
{
	unsigned long long *prime(primes), *power(powers), number(a), base(3), exponent, square_root(sqrt(number));
	if (!(number % 2))
	{
		exponent = 1;
		number >>= 1;
		while (!(number % 2))
		{
			++exponent;
			number >>= 1;
		}
		exponent *= b;
		*prime = 2;
		*power = exponent;
		++prime;
		++power;
	}
	while (number != 1 && base < square_root)
	{
		if (!(number % base))
		{
			exponent = 1;
			number /= base;
			while (!(number % base))
			{
				number /= base;
				++exponent;
			}
			exponent *= b;
			*prime = base;
			*power = exponent;
			++prime;
			++power;
		}
		base += 2;
	}
	if (number != 1)
	{
		*prime = number;
		*power = b;
	}
}

inline int pow (unsigned long long base, unsigned long long exponent)
{
	unsigned long long result(1);
	while (exponent)
	{
		if (exponent & 0x01)
			result = (result * base) % MOD;
		base = (base * base) % MOD;
		exponent >>= 1;
	}
	return result;
}

inline void compute (void)
{
	int i(0);
	unsigned long long progression;
	while (primes[i])
	{
		if (powers[i] == 1)
			progression = 1 + primes[i];
		else
		{
			
			if (primes[i] % MOD == 1)
			{
				result *= (powers[i] + 1) % MOD;
				result %= MOD;
				++i;
				continue;
			}
			progression = pow(primes[i] % MOD,powers[i] + 1);
			if (!progression)
				progression = MOD - 1;
			else
				--progression;
		}
		progression *= pow(primes[i] - 1,MOD - 2);
		progression %= MOD;
		result *= progression;
		result %= MOD;
		++i;
	}
}

int main (void)
{
	std::freopen("sumdiv.in","r",stdin);
	std::freopen("sumdiv.out","w",stdout);
	read();
	primes_decomposition();
	compute();
	print();
	return 0;
}