题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2818
题目要求的是下面这个东西↓
其实这个东西和下面这个东西是等价的↓
然后就是欧拉函数的裸题,phi(i)的前缀和弄一下
最后ans*2就好了
不过要注意的是当p为素数时,(p,p)会被重复计算,所以最后答案要减去素数个数贴代码↓
#include<cstdio>
#include<cstring>
int phi[10000005],prime[10000005];
int n,cnt;
long long ans;
long long f[10000005];
bool vis[10000005];
using namespace std;
int main(){
// freopen("2818.in","r",stdin);
// freopen("2818.out","w",stdout);
scanf("%d",&n);
memset(vis,0,sizeof(vis));
memset(phi,0,sizeof(phi));
cnt=0;f[1]=phi[1]=1;
for (int i=2;i<=n;i++){
if (!vis[i]) prime[++cnt]=i,phi[i]=i-1;
for (int j=1;j<=cnt&&prime[j]*i<=n;j++){
vis[prime[j]*i]=1;
if (i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}else phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
f[i]=f[i-1]+phi[i];
}
ans=0;
for (int i=1;i<=cnt;i++)ans+=f[n/prime[i]];
ans*=(long long)(2);
printf("%lld",ans-cnt);
return 0;
}
【写的有漏洞的,欢迎路过大神吐槽】
2016/12/23 20:28:45
Ending.