题意:
要你求出gcd(1,2) + gcd(1, 3) + gcd(2, 3) + gcd(1, 4) + gcd(2, 4) + ... + gcd(n-1, n)
现在假设 d[n] = gcd(1, n) + gcd(2, n) + .. + gcd(n-1, n)
题目要求的ans[n] = ans[n-1] + d[n]
求d[n] 可以枚举n的因子,然后利用欧拉函数求出所有的gcd(i, n),欧拉函数可以预处理筛选~这题还是很巧妙的
#include <stdio.h>
#define LL long long
const int maxn = 4001000;
int phi[maxn];
LL d[maxn], print[maxn];
void get_euler() {
int i, j;
phi[1] = 1;
for(i = 2;i <= maxn; i++) if(!phi[i])
for(j = i;j <= maxn; j += i) {
if(!phi[j]) phi[j] = j;
phi[j] = phi[j] - phi[j]/i;
}
}
int main() {
get_euler();
int i, j, n;
for(i = 1;i*i <= maxn; i++)
for(j = i*2;j <= maxn;j += i) {
if(i*i == j || i == 1)
d[j] += phi[j/i]*i;
else if(i*i < j)
d[j] += (LL)phi[j/i]*i + (LL)phi[i]*j/i;
}
print[2] = d[2];
for(i = 3;i <= maxn; i++) print[i] = print[i-1]+d[i];
while(scanf("%d", &n) != -1 && n) {
printf("%lld\n", print[n]);
}
return 0;
}