题意:给定一个整数N,求出∑ni=1gcd(i,N).
解法:先求出N的所有约数(第i个记为ai),再求∑ni=1ϕ(N÷ai)即可.
AC code:
#include <cstdio>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
ll n,y=1,ans;
vector<ll> a;
map<ll,ll> tot;
ll power(ll x,ll y){
if(!y) return 1;
ll t=power(x,y>>1);
t*=t;
if(y&1) t*=x;
return t;
}
void work(ll k){
if(k==a.size()){
if(!y) return ;
ll t=n/y,fi=1;
for(ll j=2;j*j<=t;j++){
ll cnt=0;
while(!(t%j)){
cnt++;t/=j;
}
if(cnt) fi*=power(j,cnt-1)*(j-1);
}
if(t!=1) fi*=t-1;
ans+=fi*y;
return ;
}
for(ll i=0;i<=tot[a[k]];i++){
y*=power(a[k],i);
work(k+1);
y/=power(a[k],i);
}
}
int main(){
scanf("%lld",&n);
if(n==1){
printf("1\n");
return 0;
}
ll t=n;
for(ll i=2;i*i<=n;i++){
if(t%i) continue;
a.push_back(i);
while(!(t%i)){
tot[i]++;t/=i;
}
}
if(t!=1){
a.push_back(t);
tot[t]++;
}
work(0);
printf("%lld\n",ans);
return 0;
}