欲求 (sum_{i=1}^n (i,n))。
显然 ((i,n) mid n)。记 (d=(i,n)),枚举 (d),有多少个 (i in [1,n]) 使得 ((i,n)=d) 呢?换句话说有多少个 (i in [1,lfloor n/d floor]) 使得 ((i,lfloor n/d floor) = 1) 呢?显然是 (varphi(lfloor n/d floor)) 个。
答案就是 (sum_{d|n}dcdot varphi(n/d))。
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
ll n, T;
ll ans;
ll phi(ll x){
ll re=x;
for(ll i=2; i*i<=x; i++)
if(x%i==0){
re = re / i * (i - 1);
while(x%i==0) x /= i;
}
if(x>1) re = re / x * (x - 1);
return re;
}
int main(){
while(scanf("%d", &n)!=EOF){
ans = 0;
for(ll i=1; i*i<=n; i++)
if(n%i==0){
ans += (ll)i * phi(n/i);
if(i*i!=n) ans += (ll)(n/i) * phi(i);
}
printf("%lld
", ans);
}
return 0;
}