Pagini recente » Cod sursa (job #15059) | Cod sursa (job #1362681) | Cod sursa (job #3005442) | Cod sursa (job #1250410) | Cod sursa (job #2725673)
#include <bits/stdc++.h>
#define ll long long
#define MOD 9973
using namespace std;
ifstream in("ssnd.in");
ofstream out("ssnd.out");
int t;
ll n;
ll fast_pow(ll n, ll p) {
ll ans = 1;
int lim = 64 - __builtin_clzll(p);
for (int i = 0; i <= lim; i++) {
if (p & (1ll << i)) {
ans = (ans * n) % MOD;
}
n = (n * n) % MOD;
}
return ans;
}
ll inverse(ll n) {
return fast_pow(n, MOD - 2);
}
namespace sieve {
vector<int> primes;
vector<int> lp;
const int limit = 1e6; // change accordingly
int primesCount = 0;
// classic sieve
void build() {
bitset<limit + 1> marked;
for (int i = 2; i <= limit; i++) {
if (!marked[i]) {
primes.push_back(i);
primesCount++;
for (int j = i + i; j <= limit; j += i) {
marked[j] = 1;
}
}
}
}
// linear sieve that also computes lp[i] = least prime factor of i
void build_linear() {
lp = vector<int>(limit + 1);
for (int i = 2; i <= limit; i++) {
if (!lp[i]) {
lp[i] = i;
primes.push_back(i);
primesCount++;
}
for (int j = 0; j < (int) primes.size() && primes[j] <= lp[i] && primes[j] * i <= limit; j++) {
lp[i * primes[j]] = primes[j];
}
}
}
// merges two decompositions
template<typename T>
vector<pair<T, int> > merge(const vector<pair<T, int> > &d1, const vector<pair<T, int> > &d2) {
vector<pair<T, int> > decomposition;
int sz1 = d1.size();
int sz2 = d2.size();
int p1 = 0, p2 = 0;
while (p1 < sz1 && p2 < sz2) {
while (p1 < sz1 && p2 < sz2 && d1[p1].first < d2[p2].first) {
decomposition.push_back(d1[p1]);
p1++;
}
while (p1 < sz1 && p2 < sz2 && d1[p1].first > d2[p2].first) {
decomposition.push_back(d2[p2]);
p2++;
}
while (p1 < sz1 && p2 < sz2 && d1[p1].first == d2[p2].first) {
decomposition.push_back({d1[p1].first, d1[p1].second + d2[p2].second});
p1++;
p2++;
}
}
if (p1 < sz1) {
while (p1 < sz1) {
decomposition.push_back(d1[p1]);
p1++;
}
}
if (p2 < sz2) {
while (p2 < sz2) {
decomposition.push_back(d2[p2]);
p2++;
}
}
return decomposition;
}
// should be used for numbers up to limit, uses lp vector
template<typename T>
vector<pair<T, int> > decomposeWithLP(T n) {
vector<pair<T, int> > decomposition;
int pv = -1;
while (n > 1) {
if (lp[n] != pv) {
pv = lp[n];
decomposition.push_back({lp[n], 1});
} else {
decomposition.back().second++;
}
n /= lp[n];
}
return decomposition;
}
// can be used for numbers up to limit * limit
template<typename T>
vector<pair<T, int> > decompose(T n) {
vector<pair<T, int> > ans;
for (auto i : primes) {
if (1ll * i * i > n) {
break;
}
if (n % i) {
continue;
}
int count = 0;
while (n % i == 0) {
count++;
n /= i;
}
ans.push_back({i, count});
}
if (n > 1) {
ans.push_back({n, 1ll});
}
return ans;
}
// a mix of decompose with decomposeWithLP
template<typename T>
vector<pair<T, int> > decomposeSmart(T n) {
if (n <= limit) {
return decomposeWithLP(n);
}
vector<pair<T, int> > ans;
for (auto i : primes) {
if (1ll * i * i > n) {
break;
}
if (n % i) {
continue;
}
int count = 0;
while (n % i == 0) {
count++;
n /= i;
}
ans.push_back({i, count});
if (n <= limit) {
auto d2 = decomposeWithLP(n);
return merge(ans, d2);
}
}
if (n > 1) {
ans.push_back({n, 1ll});
}
return ans;
}
// generates all divisors of a number (into param::factors) given its prime factors decomposition
template<typename T>
void genDivisors(const vector<pair<T, int> > &decomposition, vector<T> &factors, T factor = 1, int pos = 0) {
if (pos == (int) decomposition.size()) {
factors.push_back(factor);
return;
}
for (int i = 0; i <= decomposition[pos].second; i++) {
genDivisors(decomposition, factors, factor, pos + 1);
factor *= decomposition[pos].first;
}
}
}
using namespace sieve;
void solve(const vector<int> &primes) {
in >> n;
ll div_sum = 1, div_count = 1;
auto decomp = decomposeSmart(n);
for (auto it : decomp) {
ll div = it.first, div_pow = it.second;
div = div % MOD;
div_count = div_count * (div_pow + 1) % MOD;
div_sum = (div_sum * (fast_pow(div, div_pow + 1) - 1)) % MOD;
div_sum = (div_sum * inverse(div - 1)) % MOD;
}
out << div_count << ' ' << div_sum << '\n';
}
int main() {
build_linear();
in >> t;
while (t--) {
solve(primes);
}
return 0;
}