线性筛素数
Posted acm1ruoji
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性筛素数相关的知识,希望对你有一定的参考价值。
题目链接:https://www.luogu.org/problemnew/solution/P3383
普通筛法:找到素数就把这个素数的倍数标记。以此类推。调和级数证明O(nloglogn)。这道题应该跑不过去。
#include <bits/stdc++.h> using namespace std; #define ll long long #define re register #define fi first #define se second #define mp make_pair #define pb push_back #define P pair<int,int> const int N=1e7+10; void read(int &a) { a=0; int d=1; char ch; while(ch=getchar(),ch>‘9‘||ch<‘0‘) if(ch==‘-‘) d=-1; a=ch-‘0‘; while(ch=getchar(),ch>=‘0‘&&ch<=‘9‘) a=a*10+ch-‘0‘; a*=d; } void write(int x) { if(x<0) putchar(45),x=-x; if(x>9) write(x/10); putchar(x%10+‘0‘); } bool pri[N],tot; int main() { int n,m; read(n); read(m); for(re int i=0;i<=n;i++) pri[i]=1; pri[0]=pri[1]=0; for(re int i=2;i<=n;i++) { if(pri[i]) { for(re int j=2;j*i<=n;j++) pri[j*i]=0; } } while(m--) { int a; read(a); if(pri[a]) puts("Yes"); else puts("No"); } return 0; }
线性筛法:普通筛法变形一下就可以得到这个
#include <bits/stdc++.h> using namespace std; #define ll long long #define re register #define fi first #define se second #define mp make_pair #define pb push_back #define P pair<int,int> const int N=1e7+10; void read(int &a) { a=0; int d=1; char ch; while(ch=getchar(),ch>‘9‘||ch<‘0‘) if(ch==‘-‘) d=-1; a=ch-‘0‘; while(ch=getchar(),ch>=‘0‘&&ch<=‘9‘) a=a*10+ch-‘0‘; a*=d; } void write(int x) { if(x<0) putchar(45),x=-x; if(x>9) write(x/10); putchar(x%10+‘0‘); } bool pri[N]; int prim[N],tot; int main() { int n,m; read(n); read(m); pri[0]=pri[1]=1; for(re int i=2;i<=n;i++) { if(!pri[i]) prim[tot++]=i; for(re int j=0;j<tot&&prim[j]*i<=n;j++) { pri[i*prim[j]]=1; if(i%prim[j]==0)///一个数可以用一个小的合数乘一个较大的合数,那么也可以一个大的合数乘一个小的素数,所以如果遇到i%prim[j]==0,就break,防止重复运算 break; } } while(m--) { int a; read(a); if(!pri[a]) puts("Yes"); else puts("No"); } return 0; }
还有一个用六的倍数做判断素数:原理就是除了2,3之外的所有素数 ,都是6的倍数+1或者-1
#include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <set> #include <map> #include <functional> #include <stack> #include <queue> #include <vector> #include <string> #include <cstring> #include <sstream> using namespace std; #define ll long long void read(int &a) { a=0; int d=1; char ch; while(ch=getchar(),ch>‘9‘||ch<‘0‘) if(ch==‘-‘) d=-1; a=a*10+ch-‘0‘; while(ch=getchar(),ch>=‘0‘&&ch<=‘9‘) a=a*10+ch-‘0‘; a*=d; } void write(int x) { if(x<0) putchar(45),x=-x; if(x>9) write(x/10); putchar(x%10+‘0‘); } bool su(int a) { if(a==1) return 0; if(a==2||a==3) return 1; if(a%6!=1&&a%6!=5) return 0; int temp=sqrt(a); for(register int i=5;i<=temp;i+=6) if(a%i==0||a%(i+2)==0) return 0; return 1; } int main() { int n,m; read(n); read(m); while(m--) { int a; read(a); if(su(a)) printf("Yes "); else printf("No "); } return 0; }
以上是关于线性筛素数的主要内容,如果未能解决你的问题,请参考以下文章