For problem statement at 0-999/900-999/950-959/955/problemE.txt this is a correct solution, but verifier at 0-999/900-999/950-959/955/verifierE.go ends with test 1 failed
input:10
7 4 6 8 8 5 4 2 7 8
expected:5
got:6
exit status 1 can you fix the verifier? package main
import (
"bufio"
"fmt"
"io"
"os"
)
const INF = int(1e9)
var (
n int
a []int
preMinP []int
sufMinQ []int
reach []int
segP []int
segQ []int
size int
data []byte
ptr int
)
func nextInt() int {
for ptr < len(data) && (data[ptr] < '0' || data[ptr] > '9') {
ptr++
}
x := 0
for ptr < len(data) && data[ptr] >= '0' && data[ptr] <= '9' {
x = x*10 + int(data[ptr]-'0')
ptr++
}
return x
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func query(tree []int, l, r int) int {
if l > r {
return INF
}
l += size - 1
r += size - 1
res := INF
for l <= r {
if l&1 == 1 {
if tree[l] < res {
res = tree[l]
}
l++
}
if r&1 == 0 {
if tree[r] < res {
res = tree[r]
}
r--
}
l >>= 1
r >>= 1
}
return res
}
func update(tree []int, pos, val int) {
p := size + pos - 1
tree[p] = val
for p >>= 1; p > 0; p >>= 1 {
if tree[p<<1] < tree[p<<1|1] {
tree[p] = tree[p<<1]
} else {
tree[p] = tree[p<<1|1]
}
}
}
func check(t int) bool {
for T := 1; T <= n; T++ {
m := reach[T]
if m > t {
m = t
}
if m <= 0 || m >= n {
continue
}
var leftMin, rightMin int
if T > m {
leftMin = T + preMinP[m]
rightMin = T + query(segP, m+1, T)
if T < n {
v := sufMinQ[T+1] - T
if v < rightMin {
rightMin = v
}
}
} else {
leftMin = T + preMinP[T]
if T < m {
v := query(segQ, T+1, m) - T
if v < leftMin {
leftMin = v
}
}
rightMin = sufMinQ[m+1] - T
}
if leftMin <= t && rightMin <= t {
return true
}
}
return false
}
func main() {
data, _ = io.ReadAll(os.Stdin)
n = nextInt()
a = make([]int, n+1)
maxA := 0
for i := 1; i <= n; i++ {
a[i] = nextInt()
if a[i] > maxA {
maxA = a[i]
}
}
preMinP = make([]int, n+1)
preMinP[0] = INF
for i := 1; i <= n; i++ {
v := a[i] - i
if v < preMinP[i-1] {
preMinP[i] = v
} else {
preMinP[i] = preMinP[i-1]
}
}
sufMinQ = make([]int, n+2)
sufMinQ[n+1] = INF
for i := n; i >= 1; i-- {
v := a[i] + i
if v < sufMinQ[i+1] {
sufMinQ[i] = v
} else {
sufMinQ[i] = sufMinQ[i+1]
}
}
prefixMaxD := make([]int, n+1)
prefixMaxD[0] = -INF
for i := 1; i <= n; i++ {
d := 2*i - a[i]
if d > prefixMaxD[i-1] {
prefixMaxD[i] = d
} else {
prefixMaxD[i] = prefixMaxD[i-1]
}
}
size = 1
for size < n {
size <<= 1
}
segP = make([]int, 2*size)
segQ = make([]int, 2*size)
for i := range segP {
segP[i] = INF
segQ[i] = INF
}
for i := 1; i <= n; i++ {
segP[size+i-1] = a[i] - i
segQ[size+i-1] = a[i] + i
}
for i := size - 1; i > 0; i-- {
segP[i] = min(segP[i<<1], segP[i<<1|1])
segQ[i] = min(segQ[i<<1], segQ[i<<1|1])
}
pLeft := make([]int, n+1)
j := 0
for T := 1; T <= n; T++ {
for j < T && prefixMaxD[j+1] <= T {
j++
}
pLeft[T] = j
}
bucket := make([][]int, n+2)
for i := 1; i <= n; i++ {
if a[i] < n {
bucket[a[i]+1] = append(bucket[a[i]+1], i)
}
}
active := make([]int, 2*size)
for i := range active {
active[i] = INF
}
pRight := make([]int, n+1)
for T := 1; T <= n; T++ {
for _, pos := range bucket[T] {
update(active, pos, pos)
}
if T == n {
pRight[T] = n
} else {
nxt := query(active, T+1, n)
if nxt == INF {
pRight[T] = n
} else {
pRight[T] = nxt - 1
}
}
}
reach = make([]int, n+1)
for T := 1; T <= n; T++ {
if pLeft[T] < T {
reach[T] = pLeft[T]
} else {
reach[T] = pRight[T]
}
}
hi := n + maxA
out := bufio.NewWriterSize(os.Stdout, 1<<20)
defer out.Flush()
if !check(hi) {
fmt.Fprintln(out, -1)
return
}
lo := 1
for lo < hi {
mid := (lo + hi) >> 1
if check(mid) {
hi = mid
} else {
lo = mid + 1
}
}
fmt.Fprintln(out, lo)
}