- P56's solution
P56's Solution
- 2025-9-5 22:27:36 @
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;
}