Cod sursa(job #366301)

Utilizator ProtomanAndrei Purice Protoman Data 21 noiembrie 2009 14:43:12
Problema Suma divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.34 kb
#include <algorithm>
#include <stdio.h>
#include <vector>

#define restRez 9901
#define ll long long
#define pb push_back

using namespace std;

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

inline void inversModular(ll a, ll b, ll &x, ll &y)
{
	if (!b)
		x = 1, y = 0;
	else
	{
		inversModular(b, a % b, x, y);
		ll aux = x;
		x = y;
		y = aux - y * (a / b);
	}
}

inline ll put(ll f, ll e)
{
	ll r = 1;
	for (; e > 1; e /= 2)
	{
		if (e & 1)
			r = (r * f) % restRez;
		f = (f * f) % restRez;
	}

	return (f * r) % restRez;
}

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

	scanf("%lld %lld", &a, &b);

	ll AUXa = a;
	for (ll div = 2; div * div <= a; div++)
		if (AUXa % div == 0)
		{
			ll ap = 0;
			for (; AUXa % div == 0; ap++, AUXa /= div);

			vctDiv.pb(div);
			vctExp.pb(ap * b);
		}
	if (AUXa > 1)
		vctDiv.pb(AUXa), vctExp.pb(b);

	ll sol = 1;
	for (int i = 0; i < vctDiv.size(); i++)
		if (vctDiv[i] % restRez == 1)
			sol = (sol * (vctExp[i] + 1)) % restRez;
		else
		{	
			ll x = (put(vctDiv[i], vctExp[i] + 1) + restRez - 1) % restRez, inv = 0;
			inversModular(vctDiv[i] - 1, restRez, inv, AUXa);
			for (; inv < 0; inv += restRez);
			sol = (sol * x * inv) % restRez;
		}

	printf("%lld\n", sol);
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}