题意为给出几个数,对于给出的每一个数,求出∑gcd(i, N) 1<=i <=N。
可以发现规律:
因此,本题即转化为求给出数n的因子和(n/该因子)的欧拉数的乘积。
例如:给出的数为10,结果=2*(5)+5*(2);若给出的数为4,结果=2*(2);因此需要判断一下遍历到的因子i的平方是否等于给出的数n,若相等,则加一次,若不相等,需将前后数字交换,再加一次。
#include<iostream>
using namespace std;
#define ll long long
const int maxn = 1e5 + 7;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
typedef pair<int, int> pis;
int getPhi(int x) {
int rea = x;
for (ll i = 2; i * i <= x; i ++) {
if(x % i == 0) {
rea = rea - rea / i;
do{
x /= i;
}while(x % i == 0);
}
}
if(x > 1)
rea = rea - rea / x;
return rea;
}//欧拉打表
int main() {
int n;
while(cin >> n) {
ll ans = 0;
for (ll i = 1; i * i <= n; i ++) {//遍历因子
if(n % i == 0) {
ans += i * getPhi(n/i);
if(i * i != n)
ans += (n/i) * getPhi(i);
}
}//根据得出的规律进行计算
cout << ans << endl;
}
return 0;
}