首先这题如果想用O(N)做就too native了~
所以我们就要寻求更有效的算法。
其实hzwer讲得挺好的:
至于笔者一开始没想到怎么在根号时间内求phi(d)那就是笔者犯蠢了。。。直接用欧拉函数最原始的通式。。。
这题的算法上界是O(sqrt(N)*sqrt(N)),但实际上远远达不到,所以就各种怒过。
#include <stdio.h>
#include <cmath>
#include <algorithm>
using namespace std;
#define ll long long
ll n,m,ans;
ll phi(ll x){
ll t=x,p=sqrt(x);
for (ll i=2;i<=p;i++)
if (x%i==0){
t=t/i*(i-1);
for (;x%i==0;x/=i);
}
if (x>1) t=t/x*(x-1);
//如果此时x仍不等于1 说明此时的x还是个质数 而且是个大于根号x的质因数
//举个栗子:34/2=17 但是i最多枚举到根号34=6 而17又是个对结果有贡献的质因子 所以要算上
return t;
}
int main(){
scanf("%lld",&n);
m=sqrt(n);ans=0;
for (ll i=1;i<=m;i++)
if (n%i==0){
ans+=(ll)phi(n/i)*i;
if (i*i<n) ans+=(ll)n/i*phi(i);
}
printf("%lld",ans);
return 0;
}
另外怒跪笔者刚挂的期中考。。。