← Home
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)
}