2 条题解
-
1
上线性筛直接硬冲即可。
#include <bits/stdc++.h> using namespace std; int pr[17000012], cnt = 0; bitset<300000012> ppr; int up; int get() { ppr[1] = true; for (int i = 2; i <= up; i++) { if (!ppr[i]) cnt++, pr[cnt] = i; for (int j = 1; j <= cnt; j++) { if (i * pr[j] > up) break; ppr[i * pr[j]] = true; if (i % pr[j] == 0) break; } } return cnt; } int main() { int l, r; cin >> l >> r; up = r; get(); int ans = 0; for (int i = 1; i <= cnt; i++) if ((pr[i] & 3) == 1 && pr[i] >= l && pr[i] <= r) ans++; if (l <= 2 && r >= 2) ans++; cout << ans << endl; return 0; }
-
1
Algo 1
分段打表即可。
Algo 2
o3-mini 给的分段筛:
#include <iostream> #include <vector> #include <cmath> #include <algorithm> using namespace std; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); long long l, r; cin >> l >> r; // 如果 r < 2 则没有素数 if(r < 2){ cout << 0; return 0; } // 预筛出 2 ~ sqrt(r) 的素数 long long lim = static_cast<long long>(sqrt(r)) + 1; vector<bool> isPrime(lim + 1, true); isPrime[0] = isPrime[1] = false; for (int i = 2; i * i <= lim; i++){ if(isPrime[i]){ for (int j = i * i; j <= lim; j += i) isPrime[j] = false; } } vector<int> basePrimes; for (int i = 2; i <= lim; i++){ if(isPrime[i]) basePrimes.push_back(i); } // 分段筛: 每段的长度可以设为 10^6 const int segmentSize = 1000000; long long ans = 0; for(long long low = l; low <= r; low += segmentSize){ long long high = min(low + segmentSize - 1, r); vector<bool> mark(high - low + 1, true); // 对每个预筛的素数 p,在 [low, high] 上标记 p 的倍数 for (int p : basePrimes) { // 找到 [low, high] 内 p 的第一个倍数 long long start = max((long long)p * p, ((low + p - 1) / p) * p); for(long long j = start; j <= high; j += p){ mark[j - low] = false; } } // 特殊处理 1 不是素数 if(low == 1) mark[0] = false; // 统计满足条件的素数 for(long long i = 0; i < mark.size(); i++){ if(mark[i]){ long long num = low + i; // 根据数论,素数可以表示为两个正整数平方和当且仅当 // num == 2 或 num % 4 == 1 if(num == 2 || num % 4 == 1) ans++; } } } cout << ans; return 0; }
- 1
信息
- ID
- 100
- 时间
- 3000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 10
- 已通过
- 2
- 上传者