Cod sursa(job #2641070)

Utilizator MarcGrecMarc Grec MarcGrec Data 9 august 2020 20:16:09
Problema Suma si numarul divizorilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.05 kb
#define MOD 9973
#define CIUR 1000000

#include <fstream>
#include <bitset>
#include <vector>
#include <utility>
using namespace std;

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

int64_t XlaN(int64_t x, int64_t n);

int64_t InversModular(int64_t a);

void Rezolva(int64_t n);

bitset<CIUR + 1> nonprim;
vector<int64_t> nrprime;

int main()
{
	nonprim[0] = nonprim[1] = true;
	
	for (int64_t i = 1; (i * i) <= CIUR; ++i)
	{
		if (!nonprim[i])
		{	
			for (int64_t j = 2; (i * j) <= CIUR; ++j)
			{
				nonprim[i * j] = true;
			}
		}
	}
	
	for (int64_t i = 2; i <= CIUR; ++i)
	{
		if (!nonprim[i])
		{
			nrprime.push_back(i);
		}
	}
	
	int64_t t, n;
	
	fin >> t;
	
	for (int64_t i = 1; i <= t; ++i)
	{
		fin >> n;
		
		Rezolva(n);
	}
	
	fin.close();
	fout.close();
	return 0;
}

int64_t XlaN(int64_t x, int64_t n)
{
	if (n == 0)
	{
		return 1;
	}
	
	int64_t P = XlaN(x, n / 2);
	P = (P * P) % MOD;
	
	if ((n % 2) == 0)
	{
		return P;
	}
	else
	{
		return (x * P) % MOD;
	}
}

int64_t InversModular(int64_t a)
{
	return XlaN(a, MOD - 2);
}

void Rezolva(int64_t n)
{
	int64_t NR = 1;
	int64_t NUMA = 1, NUMI = 1;
	
	for (const auto& nrprim : nrprime)
	{
		if ((nrprim * nrprim) > n)
		{
			break;
		}
		
		int64_t exp = 0;
		
		while ((n % nrprim) == 0)
		{
			++exp;
			n /= nrprim;
		}
		
		NR = (NR * (exp + 1)) % MOD;
		
		if (exp > 0)
		{
			int64_t aux = XlaN(nrprim, exp + 1) - 1;
			
			if (aux < 0)
			{
				aux += MOD;
			}
			
			NUMA = (NUMA * aux) % MOD;
			NUMI = (NUMI * (nrprim - 1)) % MOD;
		}
	}
	
	if (n != 1)
	{	
		int64_t nrprim = n;
		
		int64_t exp = 0;
		
		while ((n % nrprim) == 0)
		{
			++exp;
			n /= nrprim;
		}
		
		NR = (NR * (exp + 1)) % MOD;
		
		if (exp > 0)
		{
			int64_t aux = XlaN(nrprim, exp + 1) - 1;
			
			if (aux < 0)
			{
				aux += MOD;
			}
			
			NUMA = (NUMA * aux) % MOD;
			NUMI = (NUMI * (nrprim - 1)) % MOD;
		}
	}
	
	fout << NR << ' ' << ((NUMA * InversModular(NUMI)) % MOD) << '\n';
}