Cod sursa(job #756383)

Utilizator Robert_MarksonTiberiu Popa Robert_Markson Data 9 iunie 2012 16:16:02
Problema Suma divizorilor Scor 70
Compilator cpp Status done
Runda Remember Mihai Pătrașcu Marime 2.82 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();
	
	int res = 1;
	if (n == 0) {
		res = 0;
	} else if (k == 0) {
		res = 1;
	} else {
		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));
		
		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;
}