Cod sursa(job #166695)

Utilizator scvalexAlexandru Scvortov scvalex Data 28 martie 2008 13:06:05
Problema Suma divizorilor Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.26 kb
#include <iostream>

#define MOD 9901

using namespace std;

int N, K;

int logpow(int A, int B) {
	int R(1);
	for (int i = 1 << 30; i > 0; i >>= 1) {
		R = (R * R) % MOD;
		if (i & B)
			R = (R * A) % MOD;
	}
	return R;
}

int logpow2(int A, int B) {
	if (B == 0)
		return 1;
	int aux = logpow2(A, B / 2);
	aux = (aux * aux) % MOD;
	if (B % 2 == 1)
		aux = (aux * A) % MOD;
	return aux;
}

int progresie(int p, int q) {
	int a = (logpow2(p, q+1) - 1 + MOD) % MOD;
	int b = p - 1;
	
	int c;
	for (c = 1; c <= MOD; ++c)
		if ((c * b) % MOD == a)
			break;
	return c % MOD;
}

int progresie2(int p, int q) {
	if (p == 1)
		return (q + 1) % MOD;
	int a = (logpow2(p, q + 1) + MOD - 1) % MOD;
	int b = (p + MOD - 1) % MOD;
	int c;
	for (c = 1; c <= MOD; ++c)
		if ((c * b) % MOD == a)
			break;
	//cout << a << " " << b << " " << c << endl;
	return c;
}

int main(int argc, char *argv[]) {
	FILE *fi = fopen("sumadiv.in", "r");
	fscanf(fi, "%d %d", &N, &K);
	fclose(fi);

	int S(0);
	int d(2);
	while (d*d <= N) {
		if (N % d == 0) {
			int p;
			for (p = 0; N % d == 0; ++p)
				N /= d;
			S = (S + progresie2(d % MOD, K*p)) % MOD;
		}
		++d;
	}
	if (N > 1)
		S = (S + progresie2(N % MOD, K)) % MOD;

	FILE *fo = fopen("sumadiv.out", "w");
	fprintf(fo, "%d\n", S);
	fclose(fo);

	return 0;
}