点击这里查看原题
先跑一遍线性素数筛,然后枚举每个小于n的素数,求gcd(x,y)为素数的对数即为求gcd(x/prime[i],y/prime[i])=1的对数,因此对于用n去除得到的每个素数。
剩下的部分类似于HDU 2841
/*
User:Small
Language:C++
Problem No.:2818
*/
#include<bits/stdc++.h>
#define ll long long
#define inf 999999999
using namespace std;
const int M=1e7+5;
int n,prime[1000005],tot,mu[M];
ll ans;
bool np[M];
int main(){
freopen("data.in","r",stdin);//
mu[1]=1;
for(int i=2;i<=(int)1e7;i++){
if(!np[i]){
prime[++tot]=i;
mu[i]=-1;
}
for(int j=1;j<=tot&&(ll)prime[j]*i<=1e7;j++){
np[prime[j]*i]=1;
if(i%prime[j]==0){
mu[prime[j]*i]=0;
break;
}
mu[prime[j]*i]=-mu[i];
}
}
scanf("%d",&n);
for(int k=1;prime[k]<=n;k++){
int t=n/prime[k];
for(int i=1;i<=t;i++)
ans+=(ll)(t/i)*(t/i)*mu[i];
}
printf("%lld\n",ans);
return 0;
}