【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 }
View Code

 

posted @ 2016-02-28 19:12  DMoon  阅读(141)  评论(0编辑  收藏  举报