Pagini recente » Agm 2018 Runda 1 | Cod sursa (job #933741) | Cod sursa (job #3216364) | Cod sursa (job #1844325) | Cod sursa (job #3297963)
#include <fstream>
#include <vector>
#include <bitset>
#define pb push_back
#define endl '\n'
#define int long long
using namespace std;
ifstream fin("ssnd.in");
ofstream fout("ssnd.out");
const int NMAX = 1e6 + 5;
const int MOD = 9973;
vector<int> primes;
bitset<NMAX> ciur;
int mx = 0;
int ridicare(int a, int b)
{
int p = 1;
a %= MOD;
while (b)
{
if (b & 1) p = (p * a) % MOD;
a = (a * a) % MOD;
b >>= 1;
}
return p;
}
void eratostene()
{
primes.pb(2);
ciur[0] = 1;
ciur[1] = 1;
for (int i = 4; i < NMAX; i += 2)
ciur[i] = 1;
for (int i = 3; i * i < NMAX; i += 2)
{
if (!ciur[i])
{
for (int j = i * i; j < NMAX; j += i * 2)
ciur[j] = 1;
}
}
for (int i = 3; i < NMAX; i += 2)
{
if (!ciur[i])
primes.pb(i);
}
mx = primes.size();
}
signed main()
{
eratostene();
int t; fin >> t;
while (t--)
{
int n; fin >> n;
int n_vechi = n;
int cnt = 0;
int d = 1;
int s = 1;
if (!ciur[n]) // prime
{
fout << "2 " << (n + 1) % MOD << endl;
continue;
}
while (n > 1 && cnt < mx)
{
int p = primes[cnt];
int cati = 0;
if (n % p == 0)
{
while (n % p == 0)
{
cati++;
n /= p;
}
cati++;
d = (d * cati) % MOD;
int part = (ridicare(p, cati) - 1 + MOD) % MOD;
int inv = ridicare(p - 1, MOD - 2);
int val = (part * inv) % MOD;
s = (s * val) % MOD;
}
// Check next prime boundary and overflow possibility
if (cnt + 1 >= mx || (primes[cnt + 1] * primes[cnt + 1] > n))
{
if (n > 1)
{
cati = 2;
p = n;
d = (d * cati) % MOD;
int part = (ridicare(p, cati) - 1 + MOD) % MOD;
int inv = ridicare(p - 1, MOD - 2);
int val = (part * inv) % MOD;
s = (s * val) % MOD;
n = 1;
}
break;
}
cnt++;
}
if (n > 1 && n_vechi == n)
{
fout << "2 " << (n + 1) % MOD << endl;
continue;
}
fout << d << " " << s << endl;
}
}