线性素数筛与区间素数筛

线性素数筛
每一个合数都只被它最小的素因子筛去一,筛出\([1,n]\)中的所有素数的时间复杂度为\(O(n)\)

int prime[maxn],cnt;
bool is_prime[maxn];

void sieve(int n){
	for(int i=2;i<=n;i++){
		if(is_prime[i]){
			prime[cnt++]=i;
		}
		for(int j=0;j<cnt && 1ll*i*prime[j]<=n;j++){
			is_prime[i*prime[j]]=1;
			if(i%prime[j]==0) break;
		}
	}
}

区间素数筛
筛出区间\([a,b]\)之内的素数,\(1\leq a\leq b\leq 1e10\)
\([1,b]\)内的合数的最小质因数一定小于等于\(\sqrt b\),通过埃筛筛出\([1,\sqrt b]\)中的素数的同时,将其倍数从\([a,b]\)内划去。
通过数组下标偏移记录\([a,b]\)内的素数,也就是通过下标\([0,b-a]\)表示下标\([a,b]\)

const int maxn=1e8+10;
int prime[maxn];
bool is_prime1[maxn],is_prime2[maxn];

void segment_sieve(LL a,LL b){
    LL t=sqrt(b),n=b-a+1;
    for(int i=2;i<=t;i++) is_prime1[i]=1;
    for(int i=0;i<n;i++) is_prime2[i]=1;
    for(int i=2;i<=t;i++){
        if(is_prime1[i]){
            for(int j=2*i;j<=t;j+=i) is_prime1[j]=0;
            for(LL j=max((LL)2,(a+i-1)/i)*i;j<=b;j+=i){
                is_prime2[j-a]=0;
            }
        }
    }
}
posted @ 2020-09-22 18:15  fxq1304  阅读(115)  评论(0编辑  收藏  举报