https://darkbzoj.cc/problem/2818
https://vjudge.net.cn/contest/649469#problem/Q
給定整數N,求1≤x,y≤N且gcd(x,y)為素數的數對(x,y)有多少對.
N≤10^7
分析:線性篩出不大於N的所有素數,列舉gcd(x,y)(設為p),問題轉化為求(x,y)=p的個數。
設x=x'p, y=y'p,那麼有(x,y)=1且1≤x,y≤N/p。
轉化為求(x,y)=1且1≤x,y≤n的個數。
求(x,y)=1且1≤x,y≤N的個數:
若x≥y,對於x=1..n,有ϕ(x)個y滿足(x,y)=1
若x≤y,對於y=1..n,有ϕ(y)個x滿足(x,y)=1
若x=y,只有一種情況:(x=1, y=1)
所以答案為2(ϕ(1)+...+ϕ(n))-1
線性篩篩出尤拉函式、預處理字首和即可
#include<iostream>
#define int long long
using namespace std;
const int N=10000010;
int n,p[N/10],cnt,phi[N];
typedef long long ll;
ll ans;
bool st[N];
signed main(){
#ifdef LOCAL
freopen("1.txt","r",stdin);
#endif
#ifndef LOCAL
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
#endif
cin>>n;
phi[1]=1;
for(int i=2,k;i<=n;++i){
if(!st[i])st[i]=1,p[++cnt]=i,phi[i]=i-1;
for(int j=1;(k=p[j]*i)<=n;++j){
st[k]=1;
if(i%p[j]==0){
phi[k]=phi[i]*p[j];
break;
}
else phi[k]=phi[i]*(p[j]-1);
}
}
for(int i=2;i<=n;++i)phi[i]+=phi[i-1];
for(int i=1;i<=cnt;++i){
int nn=n/p[i];
ans+=2*phi[nn]-1;
}
cout<<ans;
return 0;
}