Cod sursa(job #289205)

Utilizator rupraRupra C rupra Data 26 martie 2009 15:49:23
Problema Suma divizorilor Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.43 kb
#include <algorithm>
#include <stdio.h>
#include <vector>

#define restRez 9901
#define ll long long
#define pb push_back
#define mp make_pair
#define f first
#define s second

using namespace std;

ll a, b;
vector <pair <ll, ll> > vctDiv;

void euclidExtins(ll a, ll b, ll &x, ll &y)
{
	if (!b)
	{
		x = 1;
		y = 0;
		
		return;
	}
	
	euclidExtins(b, a % b, x, y);
	ll xp = x;
	x = y;
	y = xp - (a / b) * y;
}	

ll ridLaPutere(ll x, ll exp)
{
	ll r = 1, nr = x % restRez;
	for (; exp > 1; r %= restRez, nr %= restRez, exp /= 2)
	{
		if (exp & 1)
			r *= nr;
		nr *= nr;
	}
	
	return (r * nr) % restRez;
}		

ll calc(ll fact, ll exp)
{
	ll p, AUX, invMod;
	p = ridLaPutere(fact, exp);
	
	p = p + restRez - 1;
	
	euclidExtins(fact - 1, restRez, invMod, AUX);
	if (invMod < 0)
		invMod += restRez;
	
	p = (p * invMod) % restRez;
	
	return p;
}

int main()
{
	freopen("sumdiv.in", "r", stdin);
	freopen("sumdiv.out", "w", stdout);
	
	scanf("%d %d", &a, &b);
	
	ll x = a;
	for (ll i = 2; i * i <= a; i++)
		if (x % i == 0)
		{
			ll exp = 0;
			
			for (; x % i == 0; exp++, x /= i);
			
			vctDiv.pb(mp(i, exp * b + 1));
		}
	if (x > 1)
		vctDiv.pb(mp(x, b + 1));
	
	ll sol = 1;
	for (ll i = 0; i < vctDiv.size(); i++)
		if (vctDiv[i].f % restRez)

		sol = (sol * calc(vctDiv[i].f, vctDiv[i].s)) % restRez;
	
	printf("%d\n", sol);

	fclose(stdin);
	fclose(stdout);
	return 0;
}