【BZOJ2818】Gcd 欧拉筛
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
Source
题解:首先我们要求Σgcd(x,y)=p (p为素数)=> Σgcd(x/p,y/p)=1 那么我们就可以枚举p,求y/p的欧拉函数的前缀和辣,又因为数对是有序的,所以结果×2还要减去n以内质数次,为什么,我也没想清楚。。。一定要想清楚。。。
大概是想清楚了,因为每次统计时(1,1)都被统计了2次所以每次减去1,公n以内的质数次。nice!!
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define N 10000000 5 using namespace std; 6 int flag[N+1000],prime[N+1000]; 7 long long phi[N+1000],ans; 8 int n,k; 9 void calcphi() 10 { 11 phi[1]=1; 12 for (int i=2;i<=n;i++) 13 { 14 if (!flag[i]) 15 { 16 prime[++k]=i; 17 phi[i]=i-1; 18 } 19 for (int j=1;j<=k&&i*prime[j]<=n;j++) 20 { 21 flag[i*prime[j]]=1; 22 if (i%prime[j]==0) 23 { 24 phi[i*prime[j]]=phi[i]*prime[j]; 25 break; 26 } 27 else phi[i*prime[j]]=phi[i]*(prime[j]-1); 28 } 29 } 30 } 31 32 int main() 33 { 34 scanf("%d",&n); 35 calcphi(); 36 for (int i=1;i<=n;i++) 37 phi[i]+=phi[i-1]; 38 for (int i=1;i<=k;i++) 39 ans+=phi[n/prime[i]]; 40 printf("%lld",ans*2-k); 41 return 0; 42 }
—Anime Otaku Save The World.