素数筛

埃式筛法

以素数的倍数一定不是素数,在判断一个素数之后将它的倍数都筛掉

const int N = 1e7 ; //1e7约为10M
int pirme[N] ; // 存放素数
bool vis[N] ; // 判断素数是否被筛掉
int init(int n){	//计算2 - n 内的素数 
	int pos = 0  ; 
	for (int i = 0 ; i <= n ; ++ i)		vis[i] = false ; 
	for (int i = 2 ; i <= n ; ++ i){
		if (!vis[i])	prime[pos++] = i ; 
		for (int j = 2*i ; j <= n ; j += i)	//i的倍数都不是素数,筛掉 
			vis[j] = true ; 
	}
	return pos ; //返回素数个数 
} 
欧拉筛法

在埃式筛法中,有可能重复筛掉合数,比如6会被2和3筛掉,在欧拉筛法中,在外层枚举 i ,当i为素数时,在内层循环枚举 j (第j个素数),筛掉 i * prime[j] ,如果i%prime[j] == 0时,相当于i = prime[j] * k (k为一个正整数) ,那么如果后面继续枚举到一个素数prime[m],就要筛去 i*prime[m],也就是prime[j] k prime[m] ,因为我们枚举素数是从小到大的,所以筛去i * prime[m] 的最小质因子应该是prime[j] ,若继续枚举就会出现冗余。例如:当 i=8 时,j = 0,prime[j] = 2 如果不跳出循环prime[j+1] = 3,8 * 3 = 2 * 4 * 3 = 2 * 12,在i = 12时会再次计算。

#include <cstdio>
const int N = 1e8 + 5 ; 
int prime[N] , vis[N] ;
int init(int n){
	int pos = 0 ;
	for (int i = 2 ; i <= n ; ++ i){
		if (!vis[i])
			vis[i] = 1 , prime[pos++] = i ; 
		for (int j = 0 ; j < pos ; ++ j){
			if (i*prime[j] > n)		break ; 		
			vis[i*prime[j]] = 1 ; 
			if (i%prime[j] == 0)	break ; 
		}
	}
	return pos ; //返回素数个数 
}
int main(){
	
	return 0 ; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值