Cod sursa(job #1065776)

Utilizator DuxarFII-Stefan-Negrus Duxar Data 23 decembrie 2013 17:55:05
Problema Suma divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.4 kb
#include<cstdio>
#include<vector>
#define NMAX 5000
#define MOD 9901
#define LL long long
using namespace std ;

LL A, B, N, sum = 1 ;
vector<LL> prime(NMAX) ;
vector<LL> nrp(NMAX) ;

void fact(LL A) ;
void solve() ;
void write() ;
LL risep(LL x, LL p) ;

int main() {
	LL i ;
	freopen("sumdiv.in", "r", stdin) ;
	freopen("sumdiv.out", "w", stdout) ;
	scanf("%lld %lld", &A, &B) ;
	fact(A) ;
	//printf("%lld\n", N) ;
	for (i = 1; i <= N; ++i) {
		nrp[i] *= B ;
	}
	solve() ;
	write() ;
	return 0 ;
}

void fact(LL A) {
	LL p ;
	N = 0 ;
	if (A % 2 == 0) {
		++N ;
		prime[N] = 2 ;
		while(A % 2 == 0) {
			A /= 2 ;
			++nrp[N] ; 
		}
	}
	for (p = 3; p * p <= A; p += 2) {
		if (A % p == 0) {
			++N ;
			prime[N] = p ;
			while(A % p == 0) {
				A /= p ;
				++nrp[N] ; 
			}
		}
	}
	if (A > 1) {
		++N;
		prime[N] = A ;
		nrp[N] = 1;
	}
}


void solve() {
	LL i, A, B = 1 ;
	for (i = 1; i <= N; ++i) {
		if ((prime[i] % MOD) == 1) {
			sum = (sum * (nrp[i] + 1)) % MOD;
		}
		else {
			B = 1 ;
			A = risep(prime[i],nrp[i] + 1) ;
			A = A + MOD - 1 ;
			A %= MOD ;
			B = risep((prime[i] - 1) % MOD, MOD - 2) ;
			sum *= (A * B) % MOD ;
			sum %= MOD ;
		}
		//printf("%lld\n\n", sum) ;
	}
}

void write() {
	printf("%lld\n", sum % MOD) ;
}

LL risep(LL x, LL p) {
	if (p == 1) return x ;
	LL result ;
	result = risep(x, p / 2) ;
	result *= result ;
	result %= MOD ;
	if ((p & 1) == 1) result *= x % MOD ;
	return result % MOD ;
}