线性筛prime/phi/miu/求逆元模板

这绿题贼水......

原理我不讲了,随便拿张草稿纸推一下就明白了。

 1 #include <cstdio>
 2 using namespace std;
 3 const long long int N=100000020;
 4 int su[N],ans,top;
 5 bool vis[N];
 6 void shai(int b)
 7 {
 8     for(int i=2;i<=b;i++)
 9     {
10         if(!vis[i])
11         {
12             su[top++]=i;
13         }
14         for(int j=0;j<top && i*su[j]<=b;j++)
15         {
16             vis[su[j]*i]=1;
17             if(i%su[j]==0) break;
18         }
19     }
20     return;
21 }
22 int main()
23 {
24     int n;
25     scanf ("%d",&n);
26     shai(n);
27     printf("%d",top);
28     return 0;
29 }
模板在此

我以前是在放屁吗......

重新证一下为什么欧拉筛只会被最小质因子筛掉一个数。

首先枚举i,然后枚举每个p与之相乘。

如果一个数a的最小质因子是p1,a = p1 * k1

a还有一个质因子是p2,a = p2 * k2,且p1 < p2

所以p1这个质数肯定在k2中。外层枚举到k2的时候,内层枚举到p1就会break,p2不会与k2匹配来筛掉a。

然后说一下线性求逆元,如何利用之前的信息?余数!假设你要求a的逆元,s < a

然后放prime/phi/miu的模板了。

 

 1 inline void getp(int n) {
 2     phi[1] = miu[1] = 1;
 3     for(int i = 2; i <= n; i++) {
 4         if(!vis[i]) {
 5             p[++top] = i;
 6             miu[i] = -1;
 7             phi[i] = i - 1;
 8         }
 9         for(int j = 1; j <= top && i * p[j] <= n; j++) {
10             vis[i * p[j]] = 1;
11             if(i % p[j] == 0) {
12                 phi[i * p[j]] = phi[i] * p[j]; /// miu[i * p[j]] = 0
13                 break;
14             }
15             miu[i * p[j]] = -miu[i]; /// get miu phi when visit 
16             phi[i * p[j]] = phi[i] * (p[j] - 1); 
17         }
18     }
19     return;
20 }
线性筛

 

posted @ 2018-03-10 14:00  huyufeifei  阅读(216)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜