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
时间: 2024-10-17 01:17:47