酷代码 AI
菜单

给定 𝐿 , 𝑅 ,请计算区间 [ 𝐿 , 𝑅 ] 中素数的个数。     1 ≤ 𝐿 ≤ 𝑅 < 2 31 , 𝑅 − 𝐿 ≤ 10 6 。 输入 第一行,两个正整数 𝐿 和 𝑅 。 输出 一行,一个整数,表示区间中素数的个数。 样例输入 复制 2 11 样例输出 复制 5 提示 70%的数据,r-l+1<=10^4 100%的数据,r-l+1<=10^6

```cpp #include <iostream> #include <vector> #include <cmath> using namespace std; int main() { long long L, R; cin >> L >> R; // 处理边界:确保L至少为2 if (L < 2) L = 2; if (R < 2) { cout << 0 << endl; return 0; } // 筛出[2, sqrt(R)]内的素数 int limit = sqrt(R); vector<bool> isPrimeSmall(limit + 1, true); vector<long long> primes; for (int i = 2; i <= limit; ++i) { if (isPrimeSmall[i]) { primes.push_back(i); for (int j = i * i; j <= limit; j += i) { isPrimeSmall[j] = false; } } } // 筛[L, R]区间 vector<bool> isPrimeLarge(R - L + 1, true); for (long long p : primes) { // 找到第一个大于等于L的p的倍数 long long start = max(p * p, (L + p - 1) / p * p); for (long long j = start; j <= R; j += p) { isPrimeLarge[j - L] = false; } } // 统计素数个数 int count = 0; for (long long i = L; i <= R; ++i) { if (isPrimeLarge[i - L]) { count++; } } cout << count << endl; return 0; } ``` 算法思路: 1. 使用埃拉托斯特尼筛法,但直接筛到2^31会超内存。 2. 利用区间长度≤10^6的特点,采用分段筛法: - 先筛出[2, sqrt(R)]内的所有素数 - 用这些素数去标记[L, R]区间内的合数 3. 注意处理L=1的特殊情况,1不是素数 4. 注意long long类型防止溢出 时间复杂度: O((R-L+1)loglogR + √R loglog√R) 空间复杂度: O(√R + (R-L+1)) 关键点: - 筛小素数时从i*i开始标记 - 筛大区间时从max(p*p, ceil(L/p)*p)开始标记 - 使用vector<bool>节省内存 [2026-01-18 12:47:23 | AI问答 | 559点数解答]

服务商
相关提问
发财导航,免费问AI
实用工具查看更多