Cod sursa(job #756417)

Utilizator Robert_MarksonTiberiu Popa Robert_Markson Data 9 iunie 2012 16:48:29
Problema Suma divizorilor Scor 90
Compilator cpp Status done
Runda Remember Mihai Pătrașcu Marime 2.55 kb
#include <fstream>
#include <iostream>
#include <utility>
#include <vector>

using namespace std;

int full_gcd(int p, int q)
{
	int a[2] = { 1, 0 }, b[2] = { 0, 1 };
	
	if (p < 0)
		p = -p;
	if (b < 0)
		q = -q;
	
	if (p < q) {
		int tmp = p;
		p = q;
		q = tmp;
	}
	
	while (q > 0) {
		int u = p / q;
		int v = p % q;
		int c[2];
		for (int i = 0; i < 2; i++)
			c[i] = b[i] + u * a[i];
		for (int i = 0; i < 2; i++)
			b[i] = a[i];
		for (int i = 0; i < 2; i++)
			a[i] = c[i];
		p = q;
		q = v;
	}
	
	// cout << "a: " << a[0] << ' ' << a[1] << endl;
	// cout << "b: " << b[0] << ' ' << b[1] << endl;
	int res = (- p * b[0]) / (a[0] * b[1] - a[1] * b[0]);
	res %= 9901;
	if (res < 0)
		res += 9901;
	return res;
}

int mod_exp(int a, long long b, int mod)
{
	int res = 1;
	int tmp = a % mod;
	
	while (b > 0) {
		while ((b & 1) == 0) {
			b >>= 1;
			tmp *= tmp;
			tmp %= mod;
		}
		res *= tmp;
		res %= mod;
		b--;
	}
	
	return res;
}

void write_result(int res)
{
	fstream g("sumdiv.out", ios::out);
	g << res << endl;
	g.close();
}

int main()
{
	vector<int> primes;
	vector< pair<int, int> > decomposition;
	int n, k;
	
	fstream f("sumdiv.in", ios::in);
	f >> n >> k;
	f.close();
	
	if (n == 0) {
		write_result(0);
		return 0;
	} else if (k == 0) {
		write_result(1);
		return 0;
	}
	
	int temp = n;
	int mult = 0;
	while ((temp & 1) == 0) {
		temp >>= 1;
		mult++;
	}
	if (mult > 0)
		decomposition.push_back(pair<int, int>(2, mult));
	
	for (int i = 3; i * i <= temp; i += 2) {
		mult = 0;
		while (temp % i == 0) {
			temp /= i;
			mult++;
		}
		if (mult > 0)
			decomposition.push_back(pair<int, int>(i, mult));
	}
	if (temp > 1)
		decomposition.push_back(pair<int, int>(temp, 1));
	
	int res = 1;
	for (vector< pair<int, int> >::iterator iter = decomposition.begin();
			iter != decomposition.end(); ++iter) {
		int down = iter->first - 1;
		down %= 9901;
		if (down == 0) {
			res *= (k + 1) % 9901;
			res %= 9901;
		} else {
			int up = mod_exp(iter->first, iter->second, 9901);
			up = mod_exp(up, k, 9901);
			up *= iter->first;
			up %= 9901;
			//long long texp = iter->second;
			//texp *= k;
			//int up = mod_exp(iter->first, texp + 1, 9901);
			up--;
			if (up < 0)
				up += 9901;
			down = full_gcd(9901, down);
			// cout << "up(" << up << ") down(" << down << ")" << endl;
			res *= up;
			res %= 9901;
			res *= down;
			res %= 9901;
			// cout << iter->first << ' ' << iter->second << endl;
		}
	}
	
	write_result(res);
	
	return 0;
}