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;
}
}
}