GCD - Extreme (II) UVA - 11426(歐拉函數!!)
阿新 • • 發佈:2018-07-13
sin spa end 是不是 ++ size stream ont 出了
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 longA[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; }
GCD - Extreme (II) UVA - 11426(歐拉函數!!)