UVA 11426 GCD - Extreme (II) (欧拉)

。。。。。。。。。。。。。。。。。。。。。。。。。。。。

题意:

∑(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]);
    }
}

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/81460201
今日推荐