Description
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.
Input
一个整数N
Output
如题
Sample Input
4
Sample Output
4
Hint
hint
对于样例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7
GCD(px,py)==p;
有GCD(x,y)==1,在1-n/p的情况数。即1-n/p的欧拉和。p为质数。
所以直接模板套上筛。。就可以了。。
注意(2,4)(4,2)是两种情况要*2.。但是(2,2)这种有不是,又要剪掉。。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int mod=1000000007;
const int maxn=10000005;
bool check[maxn]; //用于打表记录的中间量
LL sumPhi[maxn]; //前i个的欧拉函数和
int cnt,phi[maxn],prime[maxn]; //素数个数,欧拉表,素数表
//素数表是第几个素数是什么,欧拉表是i的欧拉是phi[i];
void init(int n){ //素数+欧拉表
phi[1]=1;
cnt=0;
for(int i=2;i<=n;i++){
if(!check[i]){
phi[i]=i-1;
prime[cnt++]=i;
}
for(int j=0;j<cnt;j++){
if(i*prime[j]>n)break;
check[i*prime[j]]=true;
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else{
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
sumPhi[0]=0;
for(int i=1;i<=n;i++) sumPhi[i]=(sumPhi[i-1]+phi[i]);
}
int main(){
int n;
while(cin>>n){
LL ans=0;
init(n);
for(int i=0;i<cnt;i++){
ans+=sumPhi[n/prime[i]];
}
cout<<2*ans-cnt<<endl;
}
return 0;
}