题目链接:http://poj.org/problem?id=2480
Time Limit: 1000MS Memory Limit: 65536K

Description

Longge is good at mathematics and he likes to think about hard mathematical problems which will be solved by some graceful algorithms. Now a problem comes: Given an integer N(1 < N < 2^31),you are to calculate ∑gcd(i, N) 1<=i <=N. 

"Oh, I know, I know!" Longge shouts! But do you know? Please solve it. 

Input

Input contain several test case. 
A number N per line. 

Output

For each N, output ,∑gcd(i, N) 1<=i <=N, a line

Sample Input

2
6

Sample Output

3
15

Problem solving report:

Description: 给一个数n,1<=i<=n,求gcd(i,n)之和。
Problem solving: 令d=gcd(i,n),d必然是n的因子,并且是i和n的最大公因子。求i/d和n/d互质的i在[1,n]里有几个,就等价于 1/d,2/d,...,n/d里面有几个和n/d互质,即φ(n/d)。接着求和约数为d的有φ(n/d)个,所以就是d*φ(n/d),同时把约数为n/d的加上去,i*i==n特判一下。

Accepted Code:

/* 
 * @Author: lzyws739307453 
 * @Language: C++ 
 */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int pha(int n) {
    int ans = n;
    for (int i = 2; i <= n / i; i++) {
        if (!(n % i)) {
            ans = ans / i * (i - 1);
            while (!(n % i))
                n /= i;
        }
    }
    if (n > 1)
        ans = ans / n * (n - 1);
    return ans;
}
int main() {
    int n;
    while (~scanf("%d", &n)) {
        long long ans = 0;
        for (int i = 1; i <= n / i; i++) {
            if (!(n % i)) {
                ans += i * pha(n / i);
                if (i * i != n)
                    ans += n / i * pha(i);
            }
        }
        printf("%lld\n", ans);
    }
    return 0;
}