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
思路:
该题的思路英雄哥夜深人静写算法欧拉函数章节里有讲,假设gcd(i,n)=k,那么gcd(i/k,n/k)一定等于1,只要找出有几个满足该条件成立的i,再乘以k。
因为k是n的因子,所以该题就变成了求n/k的欧拉函数。对k从1~sqrt(n)进行枚举。如果n%k==0,那么n%(n/k)==0,所以需要累加两次。
注意事项:结果应该是long long类型。(也许只有我自己在类型上面一直犯错呢 (bushi))
AC代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long
ll eula(ll n) {
ll ans = n;
for (ll i = 2; i * i <= n; i++) {
if (n % i == 0) {
ans -= ans / i;
while (n % i == 0) {
n /= i;
}
}
}
if (n > 1)ans -= ans / n;
return ans;
}
int main() {
ll n;
while (cin >> n) {
ll ans = 0;
for (ll i = 1; i * i <= n; i++) {
if (n % i == 0) {
ans += eula(n / i) * i;
if (i * i != n) {
ans += eula(i) * (n / i);
}
}
}
cout << ans << endl;
}
return 0;
}