题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70017#problem/O
题意是给你n,求所有gcd(i , j)的和,其中1<=i <j <n。
要是求gcd(n , x) = y的个数的话,那么就是求gcd(n/y , x/y) = 1的个数,也就是求n/y的欧拉函数。这里先预处理出欧拉函数,然后通过类似筛法的技巧筛选出答案累加起来。
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 const int MAXN = 4000001; 5 typedef long long LL; 6 int p[MAXN]; 7 LL a[MAXN]; 8 9 void init() { 10 for(int i = 1 ; i < MAXN ; i++) 11 p[i] = i; 12 for(int i = 2 ; i < MAXN ; i++) { 13 if(p[i] == i) { 14 for(int j = i ; j < MAXN ; j += i) 15 p[j] = p[j] / i * (i - 1); 16 } 17 } 18 for(int i = 1 ; i < MAXN ; i++) { 19 for(int j = 2 * i ; j < MAXN ; j += i) { 20 a[j] += (LL)i * (LL)p[j / i]; 21 } 22 } 23 for(int i = 2 ; i < MAXN ; i++) { 24 a[i] = a[i] + a[i - 1]; 25 } 26 } 27 28 int main() 29 { 30 init(); 31 int n; 32 while(cin >> n && n) { 33 cout << a[n] << endl; 34 } 35 }