题面很简单,就是求$ sum^{n}_{i=1} gcd(i,n) $
首先对所求式子进行变形
$$ sum^{n}_{i=1} gcd(i,n)=sum_{d|n} d*(sum^n_{i=1}gcd(i,n)==d) $$
而$ sum^n_{i=1} (gcd(i,n)==d)=sum^{frac{n}{d}}_{i=1} [gcd(i,frac{n}{d})==1]=varphi(frac{n}{d}) $
求$ varphi(frac{n}{d}) $可以在$ O(logn) $的时间内完成
同时枚举n的约数也可以在$ O(logn) $的时间内完成
因此此问题得到了解决
#include<iostream> #include<string> #include<string.h> #include<stdio.h> #include<algorithm> #include<vector> #include<queue> #include<map> using namespace std; #define int long long int n; int phi(int x) { int i,num=x,sum=0; for (i=2;i*i<=x;i++) { if (x%i==0) num=num/i*(i-1); while (x%i==0) x/=i; } if (x>1) num=num/x*(x-1); return num; } signed main() { scanf("%lld",&n); int i,ans=0; for (i=1;i*i<=n;i++) { if (n%i) continue; ans+=(i*phi(n/i)); if (i*i!=n) ans+=(n/i*phi(i)); } printf("%lld",ans); return 0; }