Cod sursa(job #3130124)

Utilizator prares06Papacioc Rares-Ioan prares06 Data 16 mai 2023 21:35:05
Problema Suma si numarul divizorilor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.81 kb
#include<fstream>
#include<vector>
#include<unordered_map>

std::ifstream fin("ssnd.in");
std::ofstream fout("ssnd.out");

#define MIL 1000001
#define MOD 9973

std::unordered_map<unsigned, unsigned short> um;
std::vector<unsigned>::iterator IT;
std::vector<unsigned> prime;
int t, n, count, numitor, numarator;

int Putere(int A, int n)
{
	if (n == 0)
		return 1;
	if (n % 2 == 1)
		return A * Putere(A, n - 1) % MOD;
	int P = Putere(A, n / 2) % MOD;
	return P * P % MOD;
}

void init_sieve() {
	std::vector<bool> ciur(MIL, false);

	ciur[0] = ciur[1] = true;

	for (int i = 2; i * i < MIL; ++i)
		if (!ciur[i])
			for (int j = i; j * i < MIL; ++j)
				ciur[i * j] = true;


	for (int i = 2; i < MIL; ++i)
		if (!ciur[i])
			prime.push_back(i);


	ciur.~vector();
}

int modInverse(int A, int M)
{
	int m0 = M;
	int y = 0, x = 1;

	if (M == 1)
		return 0;

	while (A > 1) {
		// q is quotient
		int q = A / M;
		int t = M;

		// m is remainder now, process same as
		// Euclid's algo
		M = A % M, A = t;
		t = y;

		// Update y and x
		y = x - q * y;
		x = t;
	}

	// Make x positive
	if (x < 0)
		x += m0;

	return x;
}

int main() {
	fin >> t;

	init_sieve();

	while (t--) {
		fin >> n;

		IT = prime.begin();

		count = numitor = numarator = 1;

		while (IT != prime.end() && (*IT) <= n && n != 1) {
			while (n % (*IT) == 0) {
				if (um.find(*IT) != um.end())
					++um[*IT];
				else
					um[*IT] = 1;
				n /= *IT;
			}

			++IT;
		}

		for (auto elem : um) {
			count = count * (elem.second + 1);
			numarator = (numarator * (Putere(elem.first, elem.second + 1) - 1)) % MOD;
			numitor = (numitor * (elem.first - 1)) % MOD;
		}

		um.clear();

		fout << count << " " << (numarator * modInverse(numitor, MOD)) % MOD << std::endl;
	}
}