【题目描述】
给定 $n$,求:
$$ \sum_{i = 1}^n \gcd(i, n) $$
$1 \leq n \leq 2^{32}$
【题目链接】
BZOJ 2705 Longge的问题 【SDOI 2010】
【解题思路】
$$ \begin{align*} \sum_{i = 1}^n \gcd(i, n) &= \sum_{d \mid n} \sum_{i = 1}^n d[\gcd(i, n) = d] \\ &= \sum_{d \mid n} d \sum_{i = 1}^n[\gcd(i, n) = d] \\ &= \sum_{d \mid n} d \sum_{i = 1}^{\left \lfloor \frac n d \right \rfloor}[\gcd(i, \frac n d) = 1] \\ &=\sum_{d \mid n} d \varphi(\frac n d) \end{align*} $$
因为只有一组询问,所以我们可以枚举 $n$ 的约数,然后暴力计算 $\varphi(\frac n d)$ 即可,这样是可以过的。
但在这里我们讨论一下 $f(n) = \sum_{d \mid n}d\ \varphi(\frac n d)$ ,即 $f = \varphi \times \tau$ 的筛法。
积性函数的狄利克雷卷积还是积性函数,所以我们考虑 $f(p^a)$ 即可。
$$ \begin{align*} f(p^a) &= \sum_{i = 0}^a p^i \ \varphi(p^{a - i}) \\ &= p^a + \sum_{i = 0}^{a - 1} p^i \ \varphi(p^{a - i}) \\ &= p^a + \sum_{i = 0}^{a - 1} p^i (p - 1) p^{a - i - 1} \\ &= p^a + \sum_{i = 0}^{a - 1} p^{a - 1} (p - 1) \\ &= p^a + ap^{a - 1}(p - 1) \end{align*} $$
$n$ 太大,不能用筛法(在本题中也没有必要),但我们可以分解质因数计算啦。
总结:枚举 $\gcd$,内层变量外移,然后考虑作为 $\gcd$ 的次数,这是变形的常用方法。
【AC 代码】
#include <cstdio>
#include <cmath>
inline long long calc(long long p, long long a, long long pow){
return a * (pow / p) * (p - 1) + pow;
}
int main(){
long long n;
scanf("%lld", &n);
long long m = static_cast<long long>(ceil(sqrt(n) + 0.5));
long long ans = 1;
for(long long i = 2; i <= m; i++) if(n % i == 0){
long long cnt = 0, pow = 1;
while(n % i == 0) n /= i, cnt++, pow *= i;
ans *= calc(i, cnt, pow);
}
if(n != 1){
ans *= calc(n, 1, n);
}
printf("%lld\n", ans);
return 0;
}
就是这样啦~