埃氏筛与线性筛(欧拉筛)

埃氏筛/埃拉托斯特尼筛法

C++

const int N=1e5+10;
int pri[N],cnt=0;
bool is_pri[N];
int prime(int n){
    memset(is_pri,1,sizeof(is_pri));
    is_pri[0]=is_pri[1]=0;
    for(int i=2;i<=n;i++){
        if(is_pri[i]){
            pri[cnt++]=i;
            for(int j=2*i;j<=n;j+=i)is_pri[j]=0;
        }
    }
    return cnt;//返回素数的个数
}

python

n=100
is_pri=[1]*(n+1)
pri=[]
def prime(n):
    is_pri[0]=is_pri[1]=0
    for i in range(2,n+1):
        if is_pri[i]==1 
            pri.append(i)
        for j in range(2*i,n+1,i):
            is_pri[j]=0
# testing-program
prime(n)
for i in range(len(pri)):
    print(pri[i],end=' ')

 线性筛(欧拉筛)

简单讲下原理:注意看循环中每次筛掉的合数i*pri[j],然而当i\%pri[j]==0时,则对于后面的pri[j+k]*i=pri[j+k]*pri[j]*r=pri[j]*(r*pri[j+k]),可以被更小的质数筛掉(每个合数都表示成最小质因数*某个数,保证被最小质因数筛掉)

ps:之前本人一直在考虑break后会不会后面的数会被误判为合数(只是我想多了)

对于每个x,x=pri*t,在i=t时,is\_pri[x]就会被赋值为0(在i遍历到x之前)

C++ 

const int N=1e5+10;
int pri[N],cnt=0;
bool is_pri[N];
void prime(int n){
    memset(is_pri,1,sizeof(is_pri));
    is_pri[0]=is_pri[1]=0;
    for(int i=2;i<=n;i++){
        if(is_pri[i]) pri[cnt++]=i;
        for(int j=0;j<cnt && i*pri[j]<=n;j++){
            is_pri[i*pri[j]]=0;
            if(i%pri[j]==0) break;
        }
    }
}

python

n=100
is_pri=[1]*(n+1)
pri=[]
def prime(n):
    is_pri[0] = is_pri[1] = 0
    for i in range(2,n+1):
        if is_pri[i]==1 :
            pri.append(i)
        for j in range(len(pri)):
            if i*pri[j]>n | j>=len(pri) :
                break
            is_pri[i*pri[j]] = 0
            if i%pri[j] == 0 :
                break
# testing-program
prime(n)
for i in range(len(pri)):
    print(pri[i],end=' ')

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值