[R46B]质数和
对于 的数据,,。
思路
,区间长度 很小,但每次询问都要枚举区间判断质数,逐个试除会超时。
先用 埃氏筛 预处理 的质数布尔表 isPrime:从 开始,每遇到一个仍标记为质数的 ,就把它的所有倍数 标成合数。
筛完之后,只需在 内线性扫描一遍,把 isPrime[k] 为真的 累加即可。由于区间长度不超过 ,这一步开销可以忽略。
复杂度
- 时间:埃氏筛 ,区间累加 ,总计约 。
- 空间:一个长度 的
Bool数组,约 。
仓颉实现
import std.convert.*
import std.env.*
main(): Int64 {
let reader = getStdIn()
let v = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
let L = v[0]
let R = v[1]
let nn = R + 1
let isPrime = Array<Bool>(nn, { _ => true })
isPrime[0] = false
if (R >= 1) {
isPrime[1] = false
}
var i: Int64 = 2
while (i <= R) {
if (isPrime[i]) {
var j: Int64 = i * i
while (j <= R) {
isPrime[j] = false
j += i
}
}
i += 1
}
var sum: Int64 = 0
var k: Int64 = L
while (k <= R) {
if (isPrime[k]) {
sum += k
}
k += 1
}
println(sum)
return 0
}