[R43C]序列(Medium Ver.)
数据规模:,。注意本题统计的是连续子数组,不是子序列。
思路
允许 的做法。直接枚举所有连续子数组 :固定左端点 ,让右端点 从 向右扩展。扩展过程中只需维护当前段的最大值 与最小值 ——每加入一个 ,用一次比较更新二者即可,无需重新扫描整段。
于是对每个 能在 时间内判断 是否成立,成立则计数加一。整体复杂度 。
关键在于「固定左端点、向右扩展」时 、 可以增量维护:因为向段内加入新元素只可能让最大值变大、最小值变小,不会回退,所以一次遍历就够了。
复杂度
时间 ,空间 (仅存原数组)。 时约 次比较,远在时限内。
仓颉实现
import std.convert.*
import std.env.*
main(): Int64 {
let reader = getStdIn()
let line = reader.readln().getOrThrow().split(" ", removeEmpty: true)
let n = Int64.parse(line[0])
let k = Int64.parse(line[1])
let a = reader.readln().getOrThrow().split(" ", removeEmpty: true).map({ p: String => Int64.parse(p) })
var ans = Int64(0)
for (l in 0..n) {
var mx = a[l]
var mn = a[l]
for (r in l..n) {
let v = a[r]
if (v > mx) {
mx = v
}
if (v < mn) {
mn = v
}
if (mx - mn <= k) {
ans = ans + 1
}
}
}
println(ans)
return 0
}