Cod sursa(job #2576364)

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

using namespace std;

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

const long long MOD = 9973;

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

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

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


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

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

pair<long long, long long> getInfo(long long n)
{
	long long e = 0, k = 0;
	long long cnt = 1;
	long long sum = 1;
	long long lim = (long long)sqrt((double)n);
	bool prime = true;
	while (1ll*primes[k] <= lim && n > 1)
	{
		long long d = 1ll*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, long long>info = getInfo(n);
		fout << info.first << " " << info.second << "\n";
	}
	return 0;
}