Cod sursa(job #778876)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 16 august 2012 00:32:24
Problema Suma si numarul divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.83 kb
#include <cstdio>
#include <cmath>

const unsigned int LIMIT(1000001);
const unsigned int MAX_PRIMES(78497);

bool v [LIMIT];
unsigned int primes [MAX_PRIMES];

inline void Eratosthenes (void)
{
	bool *iterator(v + 3), *end(v + LIMIT), *multiple;
	unsigned int *add_prime(primes), number;
	do
	{
		if (!*iterator)
		{
			*add_prime = number = iterator - v;
			++add_prime;
			for (number <<= 1, multiple = iterator + number ; multiple < end ; multiple += number)
				*multiple = true;
		}
		iterator += 2;
	}
	while (iterator < end);
}

inline unsigned long long power_raise (unsigned long long base, unsigned short exponent)
{
	unsigned long long result(1);
	while (exponent)
	{
		if (exponent & 0x01)
			result *= base;
		base *= base;
		exponent >>= 1;
	}
	return result;
}

int main (void)
{
	Eratosthenes();
	const unsigned int MODULO(9973);
	unsigned int t;
	std::freopen("ssnd.in","r",stdin);
	std::scanf("%u",&t);
	std::freopen("ssnd.out","w",stdout);
	unsigned int *iterator, base, sum, divisors;
	unsigned short exponent;
	unsigned long long n, *n_ptr(&n);
	do
	{
		std::scanf("%llu",n_ptr);
		divisors = sum = 1;
		if (!(n % 2))
		{
			exponent = 1;
			n >>= 1;
			while (!(n % 2))
			{
				n >>= 1;
				++exponent;
			}
			divisors = exponent + 1;
			sum = (2 << exponent) - 1;
			sum %= MODULO;
		}
		iterator = primes;
		while (n != 1)
		{
			base = *iterator;
			if (base * base > n)
				break;
			if (!(n % base))
			{
				n /= base;
				exponent = 1;
				while (!(n % base))
				{
					n /= base;
					++exponent;
				}
				++exponent;
				divisors *= exponent;
				sum = sum * ((power_raise(base,exponent) - 1) / (base - 1)) % MODULO;
			}
			++iterator;
		}
		if (n != 1)
		{
			divisors <<= 1;
			sum = sum * ((n * n - 1) / (n - 1)) % MODULO;
		}
		std::printf("%u %u\n",divisors,sum);
		--t;
	}
	while (t);
	std::fclose(stdin);
	std::fclose(stdout);
}