埃氏筛法的一般写法(区间筛法)
生活随笔
收集整理的這篇文章主要介紹了
埃氏筛法的一般写法(区间筛法)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
問題:
求 $[L, R]$ 之間的素數表
解法:
一個合數 $n$ 的最小素因子不超過 $\sqrt{n}$。
先用埃氏篩法求出 $[1,\lfloor \sqrt{R} \rfloor]$ 上的素數表
再在 $[L, R]$ 上用埃氏篩法求素數
?
const int N(1e5); bool isprime[N]; int prime[N]; void init(){memset(isprime, -1, sizeof(isprime));isprime[0]=isprime[1]=0;int np=0;for(int i=0; i<N; i++){if(isprime[i]){prime[np++]=i;for(int j=2*i; j<N; j+=i)isprime[j]=0;}} } typedef long long ll; const int M(1e5); bool ok[M]; int res[M]; int seive(ll l, ll r){ // l, r >=1memset(ok, -1, sizeof(ok));if(l==1) ok[0]=0; //error-proneint k=sqrt(r);for(int i=0; prime[i]<=k; i++){ll j=(l+prime[i]-1)/prime*prime;j=max(j, (ll)2*prime[i]);for(; j<=r; j+=prime[i])ok[j-l]=0;}int np=0;for(int i=0; i<=r-l; i++)if(ok[i]) res[np++]=i+(ll)l;return np; }?
?更新:
不必先把 $[2, \lfloor \sqrt{R} \rfloor]$ 上的素數存下來。更好的做法是先分別做好 $[2, \lfloor \sqrt{R} \rfloor]$ 和 $[L, R]$ 的表,然后從?$[2, \lfloor \sqrt{R} \rfloor]$ 的表中篩得素數的同時,也將其倍數從 $[L, R]$ 中劃去。
const int N=1e6+5, M=sqrt(1e9);bool is_prime[N]; bool is_prime_small[M+1];void segment_seive(int l, int r){ // [l,r]int t=sqrt(r);for(int i=2; i<=t; i++)is_prime_small[i]=true;for(int i=0; i<=r-l; i++)is_prime[i]=true;for(int i=2; i<=t; i++)if(is_prime_small[i]){for(int j=2*i; j<=t; j+=i)is_prime_small[j]=false;for(int j=max(2, (l+i-1)/i)*i; j<=r; j+=i)is_prime[j-l]=false;} }?
?
?
?
?
?
轉載于:https://www.cnblogs.com/Patt/p/4805212.html
總結
以上是生活随笔為你收集整理的埃氏筛法的一般写法(区间筛法)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转】深入浅出PageRank算法
- 下一篇: MariaDb数据库管理系统的学习(一)