有关素数的基础算法代码总结

1.素性测试

给定整数n,判断n是不是素数

//素性测试 
bool is_prime(int n){
	for(int i=2;i*i<=n;i++){
		if(n%i==0)return false;
	}
	return n!=1;
}
//约数枚举
vector<int> divisor(int n){
	vector<int> res;
	for(int i=1;i*i<=n;i++){
		if(n%i==0){
			res.push_back(i);
		}
		if(i!=n/i)res.push_back(n/i);
	}
	return res;
}
//整数分解 
map<int,int> prime_factor(int n){
	map<int,int> res;
	for(int i=2;i*i<=n;i++){
		while(n%i==0){
			++res[i];
			n/=i;
		}
	}
	if(n!=1)res[n]=1;
	return res;
}

2.埃氏筛法

给定一个数n,问n以内有多少个素数

int prime[MAX_N];//记录素数的值 
bool is_prime[MAX_N+1];//记录每一个数是否是素数 
int sieve(int n){
	int p=0;
	for(int i=0;i<=n;i++){
		is_prime[i]=true;
	}
	is_prime[0]=is_prime[1]=false;
	for(int i=2;i<=n;i++){
		if(is_prime[i]){
			prime[p++]=i;
			for(int j=2*i;j<=n;j+=i)is_prime[j]=false;
		}
	}
	return p;//返回区间[0,n]内素数的个数 
}

3.区间筛法

求区间[a,b)内有多少个素数

思路:

b以内的合数的最小质因数一定不超过b^1/2,如果有b^1/2以内的素数表的活,就可以吧埃氏筛法运用到[a,b)上了。也就是说,先分别做好[2,b^1/2)的的素数表和[a,b)的表,然后从[2,b^1/2)的表中筛得素数的同时,也将其倍数从[a,b)的表中划去,最后剩下的就是区间[a,b)内的素数了。

typedef long long ll;
bool is_prime[MAX_L];//[a,b)=>[a,b-a)
bool is_prime_small[MAX_SQRT_B];//[2,b^1/2)

void segment_sieve(ll a,ll b){
	for(int i=0;(ll)i*i<=b;i++)is_prime_small[i]=true;
	for(int i=0;i<b-a;i++)is_prime[i]=true;
	for(int i=2;(ll)i*i<b;i++){
		if(is_prime_small[i]){
			for(int j=2*i;(ll)j*j<b;j+=i)is_prime_small[j]=false;
			for(ll j=max(2,(a+i-1)/i)*i;j<b;j+=i)is_prime[j-a]=false;
		}
	}
}

猜你喜欢

转载自blog.csdn.net/m0_37579232/article/details/81428852