Cod sursa(job #756375)

Utilizator Robert_MarksonTiberiu Popa Robert_Markson Data 9 iunie 2012 16:06:56
Problema Suma divizorilor Scor 70
Compilator cpp Status done
Runda Remember Mihai Pătrașcu Marime 2.69 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, int b, int mod)
{
	int res = 1;
	int tmp = a % mod;
	
	while (1) {
		if (b % 2 == 1) {
			res *= tmp;
			res %= mod;
			b--;
		}
		if (b == 0)
			break;
		while ((b & 1) == 0) {
			b >>= 1;
			tmp *= tmp;
			tmp %= mod;
		}
	}
	
	if (res == 0)
		res += mod;
	
	return res;
}

int main()
{
	vector<int> primes;
	vector< pair<int, int> > decomposition;
	int n, k;
	
	fstream f("sumdiv.in", ios::in);
	f >> n >> k;
	f.close();
	
	primes.push_back(2);
	for (int i = 3; i * i <= n; i += 2) {
		bool is_prime = true;
		for (vector<int>::iterator iter = primes.begin();
				iter != primes.end(); ++iter) {
			int elem = *iter;
			if (elem * elem > elem)
				break;
			if (i % elem == 0) {
				is_prime = false;
				break;
			}
		}
		if (is_prime)
			primes.push_back(i);
	}
	
	int temp = n;
	for (vector<int>::iterator iter = primes.begin();
			iter != primes.end(); ++iter) {
		int elem = *iter;
		int mult = 0;
		while (temp % elem == 0) {
			temp /= elem;
			mult++;
		}
		if (mult > 0)
			decomposition.push_back(pair<int, int>(elem, mult));
	}
	if (temp > 1)
		decomposition.push_back(pair<int, int>(temp, 1));
	
	int res = 1;
	
	if (decomposition.size() == 1 && decomposition[0].second == 1 && decomposition[0].first % 9901 == 1) {
		res = (k + 1) % 9901;
	} else {
		for (vector< pair<int, int> >::iterator iter = decomposition.begin();
				iter != decomposition.end(); ++iter) {
			int up = mod_exp(iter->first, iter->second, 9901);
			up = mod_exp(up, k, 9901);
			up *= iter->first;
			up %= 9901;
			up--;
			if (up < 0)
				up += 9901;
			int down = iter->first - 1;
			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;
		}
	}
	
	fstream g("sumdiv.out", ios::out);
	g << res << endl;
	g.close();
	
	return 0;
}