Cod sursa(job #170901)

Utilizator scvalexAlexandru Scvortov scvalex Data 3 aprilie 2008 14:01:10
Problema Suma divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.44 kb
#include <iostream>

#define MOD 9901

using namespace std;

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

int putere(int q, int exp) { 
	int V; 
	if (!exp) 
		return 1; 
	V = putere(q, exp / 2); 
	V = (V * V) % 9901; 
	if (exp & 1) 
		V = (V * q) % 9901; 
	return V; 
} 

long progresie2(long p, long q) {
	long a = (putere(p, q+1) - 1 + MOD) % MOD;
	long b = p - 1;
	
	long c;
	for (c = 1; c <= MOD; ++c)
		if ((c * b) % MOD == a)
			break;
	return c % MOD;
}

int progresie(int q, int exp) { 
	int V; 
	
	if (q == 1) 
		V = (exp + 1) % 9901; 
	else if (exp == 1) 
		V = (1 + q) % 9901; 
	else if (exp == 0) 
		V = 1; 
	else if (exp & 1) {
		V = progresie(q, exp - 1); 
		V = (1 + ((q % 9901) * V) % 9901) % 9901;
	} else { 
		V = progresie(q, exp / 2); 
		V = (V + (logpow(q, exp / 2) * (V + 9900)) % 9901) % 9901; 
	} 
	return V; 
}

int main(int argc, char *argv[]) {
	long N, K;

	FILE *fi = fopen("sumdiv.in", "r");
	fscanf(fi, "%ld %ld", &N, &K);
	fclose(fi);

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

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

	return 0;
}