。。。。。。。。。。。。。。。。。。。。。。。。。。。。
题意:
∑(i = 1,i < N)∑(j = i + 1, j ≤ N)GCD(i, j)
思路:
一般的欧拉超时,所以要用打表的方式记录已经计算过的值
#include <stdio.h>
const int maxn = 4000005;
typedef long long ll;
int phi[maxn];
ll ans[maxn];
void solve(){
int i,j;
for(i = 1; i < maxn; i++)
phi[i] = i;
for(i = 2;i < maxn; i++){
if(phi[i] == i){
for(j = i; j < maxn; j += i){
phi[j] = (phi[j] / i) * (i-1);
}
}
}
//打表
for(i = 1; i < maxn; i++){
for(j = i; j < maxn; j += i){
ans[j] = ans[j] + i * phi[j / i];//j必定是i的倍数而且i是最大公因数,phi[j/i]是与j/i互质的数的个数,即与j最大公因数为i的数的个数
}
}
//计算每一个数的gcd()的和
for(i = 1; i < maxn; i++) ans[i] -= i;
//剪掉自身
for(i = 1; i < maxn; i++){
ans[i] += ans[i - 1];
}
//加上前面的
}
int main(){
solve();
int n;
while(scanf("%d", &n) && n) {
printf("%lld\n",ans[n]);
}
}