能够解决区间素数问题
两种筛选法
1.埃式筛选法
思路就是 一个素数的倍数必定是合数,所以这里我们对素数的倍数进行判断,对合数剪掉。一开始时假设所有都是素数,把从2开始的所有素数的倍数进行标记,剩下的就是素数。
void ptshai(){
for(int i=0;i<=n;i++) prime[i] = 1;
prime[0] = 0;
prime[1] = 0;
for(int i=2;i<=n;i++){
if(!prime[i]) continue; //如果已经是合数 则直接跳过,不用再判断
for(int j=2;j*i<=n;j++){ //只对素数的倍数进行循环
prime[i*j] = 0;
}
}
}
2.快速线性筛
这个比上面的麻烦,但是时间要快,依靠定理:任何一个合数都可以写成几个质数相乘的形式
void ksshai(){
memset(prime,true,sizeof(prime)); //假设所有的数都是素数
prime[0] = 0; //0 和 1 不是
prime[1] = 0;
for(int i=2;i<=n;i++){
if(prime[i]){ //将素数序列保存下来,并且为后面的循环提供条件
pr[ans++] = i;
}
for(int j=0;j<ans&&i*pr[j]<=n;j++){
prime[i*pr[j]] = 0; //仅仅筛掉比当前数
if(i%pr[j]==0) break; // 这里 比如一个9x5 可以被分解为 3x15
}
}
}