给定 L,R,请计算区间 [L,R] 中素数的个数。 数据范围:1≤L≤R<2^31 ,R−L≤10^6。 请使用C++解出本题。
时间: 2025-06-28 20:11:00 浏览: 10
### 使用C++实现计算区间内素数数量
对于给定的区间 \([L, R]\),可以采用埃拉托斯特尼筛法(Sieve of Eratosthenes)来高效地找出该范围内的所有素数。由于 \(R\) 的上限较大而 \(R - L\) 较小,适合先通过线性筛选预处理一部分较小质数用于后续大范围内快速判断。
#### 预处理部分质数
为了提高效率,在正式进入目标区间之前,预先利用数组标记小于等于根号\(R\)的所有合数[^1]:
```cpp
const int MAXN = sqrt(R) + 5;
bool isPrime[MAXN];
vector<int> primes;
void sieve() {
memset(isPrime, true, sizeof(isPrime));
isPrime[0] = isPrime[1] = false; // 0 和 1 不是素数
for (int i = 2; i * i <= R; ++i){
if (isPrime[i]){
for (int j = i * i; j <= min((long long)i*i, R); j += i)
isPrime[j] = false;
primes.push_back(i);
}
}
}
```
#### 计算特定区间的素数个数
接着针对具体查询区间\([L,R]\),创建一个布尔型向量`mark[]`,长度设为\(R-L+1\)并初始化全真表示未被划掉的状态;遍历已知的小于等于sqrt(R)的每一个质因数p去删除它在当前窗口中的倍数位置对应的值直到超过上界为止最后统计剩余true的数量即所求答案[^2]:
```cpp
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull segmented_sieve(ull l, ull r) {
bool mark[r-l+1];
memset(mark,true,sizeof(bool)*(r-l+1));
for(auto p : primes){
ull start_pos=max(p*p,(l+p-1)/p*p);
for(ull pos=start_pos;pos<=r;pos+=p)
mark[pos-l]=false;
}
ull count=0;
for(int i=l;i<=r;++i)
if(mark[i-l]) ++count;
return count;
}
// 主函数调用示例
int main(){
...
cout<<segmented_sieve(L,R)<<endl;
...
}
```
上述方法能够有效地解决大规模数据下的素数计数问题,并且时间复杂度相对较低,适用于题目给出的数据规模约束条件。
阅读全文
相关推荐

















