Cod sursa(job #1184587)

Utilizator crucerucalinCalin-Cristian Cruceru crucerucalin Data 13 mai 2014 12:15:59
Problema Suma si numarul divizorilor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.4 kb
#include <cstdio>

const int MOD = 9973;
const int NMAX = 1000005;
const int NMAX_DIV = 130000;

unsigned char V[NMAX/2/8 + 1];
int K, PRIM[NMAX_DIV];

void ciur(int N)
{
	int i, j;

	for (i = 1; ((i * i) << 1) + (i << 1) <= N; ++i) {
		if ((V[i >> 3] & (1 << (i & 7))) == 0) {
			for (j = ((i * i) << 1) + (i << 1); (j << 1) + 1 <= N;
			     j += (i << 1) + 1) {
				V[j >> 3] |= (1 << (j & 7));
			}
		}
	}

	PRIM[K] = 2;
	for (i = 1; (i << 1) + 1 <= N; ++i)
		if ((V[i >> 3] & (1 << (i & 7))) == 0)
			PRIM[++K] = (i << 1) + 1;
}

int exp_bit(int N, int P)
{
	int a = N, ret = 1;
	int i;

	for (i = 0; (1 << i) <= P; ++i) {
		if (((1 << i) & P) > 0)
			ret = (ret * a) % MOD;

		a = (a * a) % MOD;
	}

	return ret;
}

int main()
{
	freopen("ssnd.in", "r", stdin);
	freopen("ssnd.out", "w", stdout);

	int T;
	long long N;

	ciur(NMAX);

	scanf("%d", &T);
	for (; T; --T) {
		scanf("%lld",&N);
		
		int nr_div = 1, sum = 1;

		for (int i = 0; i <= K; ++i) {
			if (N == 1 || 1LL * PRIM[i] * PRIM[i] > N)
				break;
			if (N % PRIM[i])
				continue;

			int count = 0;
			while (N % PRIM[i] == 0) {
				N /= PRIM[i];
				++count;
			}

			nr_div *= (count + 1);
			int p1 = (exp_bit(PRIM[i], count + 1) - 1) % MOD;
			int p2 = exp_bit(PRIM[i] - 1, MOD -2) % MOD;

			sum = (((sum * p1) % MOD) * p2) % MOD;
		}
		
		if (N > 1) {
			nr_div *= 2;
			sum = (1LL * sum * (N+1)) % MOD;
		}

		printf("%d %d\n", nr_div, sum);
	}

	return 0;
}