GCD

G(i) = (gcd(1, i) + gcd(2, i) + gcd(3, i) + .....+ gcd(i-1, i))

ret = G(1) + G(2) + G(3) +.....+ G(n);

对于gcd(x,i),我们设gcd(x,i) = m 即x和i的最大公约数为m  则x/m 和 i/m 互质 然后我们求出于i/m互质的有多少个 是不是就是求出了与i最大公约数为m的有多少个。。用欧拉函数既能求出个数  。。。即为phi(i/m)个  用双重循环  外层循环为m内层循环为i, i从m+m开始遍历每次加m, 然后循环里 G(i)+= phi(i/m)*m 则就求出了G(i)

最后累加G(i) 即为答案ret

数组要开long long

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 4000001, INF = 0x7fffffff;
long long A[maxn], G[maxn], ret[maxn];
void init()
{
    for(int i=1; i<maxn; i++)
        A[i] = i;
    for(int i=2; i<maxn; i++)
        if(A[i] == i)
            for(int j=i; j<maxn; j+=i)
                A[j] = A[j]/i*(i-1);
}

int main()
{
    init();
    for(int m=1; m<maxn; m++)
        for(int i=m+m; i<maxn; i+=m)
            G[i] += A[i/m] * m;
    for(int i=2; i<maxn; i++)
        ret[i] = ret[i-1] + G[i];
    int n;
    while(cin>> n && n)
    {
        cout<< ret[n] <<endl;

    }




    return 0;
}
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
原文地址:https://www.cnblogs.com/WTSRUVF/p/9306386.html