欧拉筛法模板(线性筛)

版权声明:本文章未经博主允许不得转载 https://blog.csdn.net/qq_42217376/article/details/88418482

欧拉筛法的原理就是每一个数只能被它最小的质因子删去,并且每个数只删除一次.

#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;

const int Max_n=100005;
typedef long long LL;
int prime[Max_n],is_prime[Max_n];
int n,num;

void get_prime(){
	num=1;
	rep(i,2,n) is_prime[i]=true;//首先先把每一个数标记成素数
	//memset(is_prime[i],true,sizeof(is_prime));
	rep(i,2,n){
		if(is_prime[i]) prime[num++]=i;//如果这个数是素数,就放进素数表
		rep(j,1,num-1){
			if(i*prime[j]>n) break;//如果判断某一个数时,从某个素数开始>n了,那么乘后面的素数时,一定超出了范围.
			is_prime[i*prime[j]]=false;//先把满足条件的标记成合数.
			if(i%prime[j]==0) break;
		}
	}
} 
int main(){
	scanf("%d",&n);
	get_prime();
	rep(i,1,num-1) printf("%d%c",prime[i],i==num-1?'\n':' ');
	return 0;
}

我们可以想象如果i%prime[j]==0成立,那么i一定是一个合数(有因子),那么我们一定可以把i分解成a*b,
并且ab中 有一个数一定是素数.则有i*prime[j]=a*b*prime[j],我们假设a是i*prime[j]的最小素因子,
那么我们 遍历到b*prime[j]时一定能把i*prime[j]标记成合数,此时a是i*prime[j]的最小素数,所以在
遇到i的 时候我们直接跳出即可.

为什么if(i%prime[j]==0) break;在is_prime[i*prime[j]]=false;的后面呢?
此时是因为,我们遍历到的第一个素因子其实是2,这个素因子是最小的,
所以第一次的时候i*prime[j]一定 是被它最小的素因子筛去的.

猜你喜欢

转载自blog.csdn.net/qq_42217376/article/details/88418482