题目描述
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对.
输入输出格式
输入格式:
一个整数N
输出格式:
答案
输入输出样例
说明
对于样例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7
首先这个题可以用欧拉函数做:
这题嘛,首先我们枚举gcd(x,y)=p的p,那么gcd(x/p,y/p)肯定互质,也就是求在[1,n/p](向下取整)范围内的欧拉函数的前缀和,再乘2(因为x和y可以交换嘛),在减一,
然后也可以套反演 复杂度差不多是m×sqrt(n)
1 #include <iostream> 2 #include"cmath" 3 #include"cstring" 4 #include"algorithm" 5 #include"stdio.h" 6 using namespace std; 7 typedef long long ll; 8 9 int mu[10000005]; 10 int prime[10000005]; int prime_c; 11 int vis[10000005]; 12 int sum[10000005]; 13 ll ans;int n; 14 15 void Mu() 16 { mu[1]=1; 17 for (int i=2;i<=10000000;i++) 18 { 19 if(!vis[i])mu[i]=-1,prime[++prime_c]=i; 20 for (int j=1;j<=prime_c;j++) 21 { 22 if(1ll*prime[j]*i>1ll*10000000)break; 23 vis[i*prime[j]]=1; 24 if(i%prime[j]==0)break; 25 mu[i*prime[j]]=-mu[i]; 26 } 27 } 28 29 for (int i=1;i<=10000000;i++)sum[i]=sum[i-1]+mu[i]; 30 31 // for (int i=1;i<=100;i++)cout<<mu[i]<<" "; 32 } 33 34 inline void work(int x) 35 { 36 int a=n; a/=x; 37 for (int r,l=1;l<=a;l=r+1) 38 { 39 r=a/(a/l); 40 ans+=1ll*(sum[r]-sum[l-1])*(a/l)*(a/l); 41 } 42 43 44 } 45 46 47 int main() 48 { cin>>n; 49 Mu(); 50 for (int j=1;j<=prime_c;j++) 51 { 52 int now=prime[j];if(now>n)break; 53 work(prime[j]); 54 // cout<<prime[j]<<" "<<ans<<endl; 55 56 } 57 58 cout<<ans; 59 60 61 }