BZOJ2818Gcd 欧拉筛

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ2818Gcd 欧拉筛相关的知识,希望对你有一定的参考价值。

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

 

以上是关于BZOJ2818Gcd 欧拉筛的主要内容,如果未能解决你的问题,请参考以下文章

[BZOJ2818] Gcd (数论,欧拉函数,线性筛)

[bzoj2818]: Gcd

BZOJ-2818Gcd 线性筛

bzoj 2818 gcd 线性欧拉函数

bzoj 2818 Gcd(欧拉函数)

bzoj 2818 GCD 数论 欧拉函数