传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2818
题意要求我们计算
sigma gcd(x,y)=p => sigma gcd(x/p,y/p)=1
设f[i]为1->i中gcd(x,y)=1的个数 x,y属于i => 1+2*sigma(phi[j]) j属于(1,i]
因为phi(x)= gcd(i,x)==1的个数 且gcd(a,b)==gcd(b,a) 所以要x2
再单独计算(1,1)的特殊情况 +1
求sigma gcd(x,y)=p => sigma gcd(x/p,y/p)=1 => sigma f[n/p]
枚举p,累加
Code:
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
typedef unsigned long long LL;
LL n;
LL phi[10000001];
bool p[10000001];
LL prime[10000001];
LL f[10000001];
void get_phi(){
phi[1]=1;
for(LL i=1;i<=n;i++){
if(!phi[i])
for(LL j=i;j<=n;j+=i){
if(!phi[j])phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
}
void get_prime(){
LL m=(int)sqrt(n+0.5);
for(LL i=2;i<=m;i++){
if(!p[i])
for(LL j=i+i;j<=n;j+=i)
p[j]=1;
}
for(LL i=2;i<=n;i++)
if(!p[i])
prime[++prime[0]]=i;
}
int main(){
cin>>n;
get_phi();
get_prime();
for(LL i=3;i<=n;i++)phi[i]+=phi[i-1];
LL ans=0;
f[1]=1;
for(LL i=2;i<=n;i++)
f[i]=1+2*phi[i];
for(LL i=1;i<=prime[0];i++){
if(n/prime[i]==0)break;
ans+=f[n/prime[i]];
}
cout<<ans<<endl;
//for(LL i=1;i<=n;i++)cout<<f[i]<<" ";
//system("pause");
return 0;
}