【數論】線性篩質數
阿新 • • 發佈:2017-10-14
一次 數論 [1] utc syn else == ring tdi
核心思想:
保證每個合數只會被它的最小質因數篩去,因此每個數只會被標記一次,所以時間復雜度是O(n)
此過程中保證了兩點:
- 合數一定被幹掉了...
- 每個數都沒有被重復地刪掉
代碼
#include<iostream> #include<cstdio> #include<cstring> #define f(i,a,b) for(register int i=a;i<=b;++i) #define fd(i,a,b) for(register int i=a;i>=b;--i) using namespace std; const int N=10000000+7; int n,m,f[N],tot; bool visit[N]; //visit[i]如果被標記了 那麽就不是素數 inline int read() { int data=0,w=1; char ch=0; while(ch!=‘-‘ && (ch<‘0‘ || ch>‘9‘)) ch=getchar(); if(ch==‘-‘) w=-1,ch=getchar(); while(ch>=‘0‘ && ch<=‘9‘) data=data*10+ch-‘0‘,ch=getchar(); return data*w; } inline void write(int x) { if(x<0) putchar(‘-‘),x=-x; if(x>9) write(x/10); putchar(x%10+‘0‘); } inline void pd(int Max) { visit[1]=1; f(i,2,Max) { //枚舉每一個數 順便枚舉倍數 if(!visit[i])//要是沒標記到那麽就是素數 f[++tot]=i; for(int j=1; j<=tot && i*f[j]<=Max; j++) //這裏是枚舉前面的每一個素數 { visit[i*f[j]]=1;//把前面的素數倍數都標記上 if(i % f[j]==0) break;//如果不是最小質因子就退出 /**************************** 為什麽這句話可以忽略掉不是最小質因子 而保證時間復雜度呢 首先 visit[]裏面的素數都是嚴格遞增的 如果當前的i含有visit[j] 不妨設 i=visit[j]*k 下一個數 P=i*visit[j+1]肯定可以寫成 P=visit[j]*k*visit[j+1] 所以P肯定會在 i=k*visit[j+1] 的時候篩掉 所以這句話可以使得是最小質因子就退出 *****************************/ } } } int main() { // ios::sync_with_stdio(false); n=read(); m=read(); pd(n); f(i,1,m) { int a=read(); if(visit[a]) puts("No"); else puts("Yes"); } return 0; }
代碼引自luogu
【數論】線性篩質數