主要思路
硬推就完事了:
\[ \begin{aligned} g(n) &= \sum_{i = 1}^n \frac{n}{\gcd(i, n)} = n \sum_{d|n} \frac{1}{d} \sum_{i = 1}^n [\gcd(n, i) = d] \\ &= n \sum_{d|n} \frac{1}{d} \sum_{i = 1}^{\frac{n}{d}} [\gcd(\frac{n}{d}, i) = 1] = \sum_{d|n} \frac{n}{d} \varphi(\frac{n}{d}) = \sum_{d|n} d \varphi(d) \\ &= \sum_{d|n} d^2 \prod_{p_i} (1 – \frac{1}{p_i}) = \prod_{p_i} (1 + \sum_{g = 1}^{e_i} p_i^{2g} (1 – \frac{1}{p_i}) ) \\ &= \prod_{p_i} (1 + \sum_{g = 1}^{e_i} p_i^{2g} – \sum_{g = 1}^{e_i} p_i^{2g – 1}) = \prod_{p_i} (1 + \sum_{g = 1}^{e_i} p_i^{2g} – \frac{ \sum_{g = 1}^{e_i} p_i^{2g} }{p_i} ) \\ &= \prod_{p_i} (1 + (1 – \frac{1}{p_i}) (\sum_{g = 1}^{e_i} p_i^{2g}) ) = \prod_{p_i} (1 + (1 – \frac{1}{p_i}) \frac{p_i^2 (1 – p_i^{2e_i})}{1 – p_i^2}) \\ &= \prod_{p_i} (1 + \frac{(p_i – 1)}{p_i} \frac{p_i^2 (1 – p_i^{2e_i})}{(1 – p_i)(1 + p_i)} ) \\ &= \prod_{p_i} (1 – \frac{p_i (1 – p_i^{2e_i})}{1 + p_i} ) = \prod_{p_i} \frac{1 + p_i – p_i + p_i^{2e_i + 1}}{1 + p_i} \\ &= \prod_{p_i} \frac{p_i^{2e_i + 1} + 1}{1 + p_i} \end{aligned} \]
最后上下除一下,得到:
\[ \frac{f(n)}{g(n)} = \prod_{p_i} (1 + p_i) \]
代码
// QOJ2225.cpp
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
typedef long long ll;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
const int base[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
ll multiply(ll x, ll y, ll cmod)
{
ll tmp = (x * y - (ll)((long double)x / cmod * y + 1.0e-8) * cmod) % cmod;
return tmp < 0 ? tmp + cmod : tmp;
}
ll fpow(ll bas, ll tim, ll cmod)
{
ll ret = 1;
while (tim)
{
if (tim & 1)
ret = multiply(ret, bas, cmod);
bas = multiply(bas, bas, cmod);
tim >>= 1;
}
return ret;
}
bool millerRabin(ll curt)
{
for (auto cbase : base)
{
if (cbase == curt)
return true;
else if (cbase > curt)
return false;
ll x = fpow(cbase, curt - 1, curt), idx = curt - 1;
if (x != 1)
return false;
while (x == 1 && idx % 2 == 0)
{
idx /= 2, x = fpow(cbase, idx, curt);
if (x != 1 && x != curt - 1)
return false;
}
}
return true;
}
ll pollardRho(ll n)
{
if (n % 2 == 0)
return 2;
if (n % 3 == 0)
return 3;
ll x = 0, y = 0, c = rand() % (n - 1) + 1, bas = 1, unit = (1 << 7), factor = 1;
for (ll step = 2;; step <<= 1, y = x, bas = 1)
{
for (ll i = 1; i <= step; i++)
{
x = (multiply(x, x, n) + c) % n;
bas = multiply(bas, abs(x - y), n);
if (i % unit == 0)
{
factor = gcd(bas, n);
if (factor > 1)
return factor;
}
}
if (factor > 1 || ((factor = gcd(bas, n)) > 1))
return factor;
}
return n;
}
vector<ll> p;
void factorize(ll x)
{
if (x == 1)
return;
if (millerRabin(x))
return (void)(p.push_back(x));
ll p = x;
while (p == x)
p = pollardRho(x);
while (x % p == 0)
x /= p;
factorize(p), factorize(x);
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
ll x;
scanf("%lld", &x), p.clear(), factorize(x);
sort(p.begin(), p.end()), p.erase(unique(p.begin(), p.end()), p.end());
int ans = 1;
for (ll x : p)
ans = 1LL * ans * (x % mod + 1) % mod;
printf("%d\n", ans);
}
return 0;
}