Cod sursa(job #295564)

Utilizator ScrazyRobert Szasz Scrazy Data 3 aprilie 2009 13:41:55
Problema Suma divizorilor Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.44 kb
#include <cstdio>

#define ll long long
ll a, b;

int mod(ll a) //a mod 9901
{ 
    int res = a % 9901;
    while (res < 0) res += 9901;
    return res;
}

int put(ll a, ll b) //a - t b -re emeli mod 9901
{
    if (b == 0) return 1;
    int aux = mod(put(a, b >> 1)); //a^[b/2]
    int res = mod(aux*aux);
    if (b & 1)
	res = mod(res * a);
    return res;
}

void cmmdc(ll a, ll b, int &x, int &y)
{
    if (b == 0)
    {
	x = 1;
	y = 0;
	return ; //a divisor commun
    } 
    int x0, y0;
    cmmdc(b, a % b, x0, y0);
    x = y0;
    y = x0 - (a / b) * y0;
}

int invers(long a)
{
    int x, y; 
    cmmdc(a, 9901, x, y);
    return mod(x);
}

int progresie(ll a, ll b) //(1 + a + a^2 + ... + a ^ b)
{
    if (a == 1) return b + 1; 
    int a1 = mod(put(a, b + 1) - 1); 
    int a2 = mod(invers(a - 1));
    return mod(a1 * a2);
}

void solve(ll a, ll b)
{
    if (mod(a) == 0) 
    {
	printf("1\n");
	return ;
    }
    ll res = 0, p = 0;
    while (a % 2 == 0)
    {
	p++; 
	a /= 2;
    }
    res = mod(progresie(2, p * b));
    
    for (int i = 3; i * i <= a; i += 2)
    {
	if (a % i) continue;
	p = 0;
	while (a % i == 0)
	{
	    p++;
	    a /= i;
	}
	res = mod(res * progresie(mod(i), p * b));
    }
    if (a > 1)
	res = mod(res * progresie(mod(a), b));
    
    printf("%lld\n", res);
}

int main()
{
    freopen("sumdiv.in","r",stdin);
    freopen("sumdiv.out","w",stdout);
    scanf("%lld%lld", &a, &b);
    //a = mod(a);
    solve(a, b);

    return 0;
}