Cod sursa(job #2576310)

Utilizator ardutgamerAndrei Bancila ardutgamer Data 6 martie 2020 18:29:51
Problema Suma si numarul divizorilor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.79 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <vector>

using namespace std;

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

const int MOD = 9973;

vector<int>primes;
bool c[1000005];

inline int lgput(int n, int p)
{
	int sol = 1;
	int a = n;
	for (int i = 0; (1 << i) <= p; i++)
	{
		if ((1 << i) & p)
			sol = (sol * a) % MOD;
		a = (a * a) % MOD;
	}
	return sol;
}

inline int imod(int n)
{
	return lgput(n, MOD - 2);
}

inline void precalcPrimes(int n)
{
	c[0] = c[1] = 1;
	for (int i = 4; i <= n; i += 2)
		c[i] = 1;
	primes.push_back(2);
	int lim = (int)sqrt((double)n);
	for (int i = 3; i <= lim; i += 2)
		if (c[i] == 0) {
			primes.push_back(i);
			for (int j = i * i; j <= n; j += 2 * i)
				c[j] = 1;
		}
}

int answer(int p, int d)
{
	int val1 = (lgput(p, d + 1)-1)%MOD;
	int val2 = imod((p - 1));
	return (val1 * val2) % MOD;
}

pair<int, int> getInfo(long long n)
{
	int e = 0, k = 0;
	int cnt = 1;
	int sum = 1;
	int lim = (int)sqrt((double)n);
	bool prime = true;
	while (primes[k] <= lim && n > 1)
	{
		int d = primes[k];
		if (n % d != 0)
		{
			k++;
			continue;
		}
		e = 0;
		while (n % d == 0)
		{
			e++;
			n /= d;
		}
		if (e > 0)
		{
			prime = false;
			cnt *= (e + 1);
			sum = (sum * answer(d,e))%MOD;
		}
		k++;
	}
	if (n > 1) {
		if (prime)
		{
			return (make_pair(2, (n + 1) % MOD));
		}
		else
		{
			cnt *= 2;
			cnt %= MOD;
			sum = (sum * answer(n, 1)) % MOD;
			return make_pair(cnt, sum);
		}
	}
	return make_pair(cnt, sum);
}

int main()
{
	precalcPrimes(1000000);
	int t;
	long long n;
	fin >> t;
	while (t--)
	{
		fin >> n;
		pair<int, int>info = getInfo(n);
		fout << info.first << " " << info.second << "\n";
	}
	return 0;
}