For problem statement at 1000-1999/1500-1599/1530-1539/1534/problemF2.txt this is a correct solution, but verifier at 1000-1999/1500-1599/1530-1539/1534/verifierF2.go ends with All tests passed can you fix the verifier? package main
import (
"bufio"
"fmt"
"io"
"math/bits"
"os"
)
type FastScanner struct {
data []byte
idx int
}
func (fs *FastScanner) skip() {
for fs.idx < len(fs.data) && fs.data[fs.idx] <= ' ' {
fs.idx++
}
}
func (fs *FastScanner) nextInt() int {
fs.skip()
val := 0
for fs.idx < len(fs.data) && fs.data[fs.idx] > ' ' {
val = val*10 + int(fs.data[fs.idx]-'0')
fs.idx++
}
return val
}
func (fs *FastScanner) nextBytes() []byte {
fs.skip()
start := fs.idx
for fs.idx < len(fs.data) && fs.data[fs.idx] > ' ' {
fs.idx++
}
return fs.data[start:fs.idx]
}
type Pair struct {
dp int
far int
}
type MinHeap struct {
a []Pair
}
func less(x, y Pair) bool {
if x.dp != y.dp {
return x.dp < y.dp
}
return x.far < y.far
}
func (h *MinHeap) Push(x Pair) {
h.a = append(h.a, x)
i := len(h.a) - 1
for i > 0 {
p := (i - 1) >> 1
if !less(h.a[i], h.a[p]) {
break
}
h.a[i], h.a[p] = h.a[p], h.a[i]
i = p
}
}
func (h *MinHeap) Pop() Pair {
res := h.a[0]
last := h.a[len(h.a)-1]
h.a = h.a[:len(h.a)-1]
if len(h.a) == 0 {
return res
}
h.a[0] = last
i := 0
for {
l := i*2 + 1
if l >= len(h.a) {
break
}
r := l + 1
j := l
if r < len(h.a) && less(h.a[r], h.a[l]) {
j = r
}
if !less(h.a[j], h.a[i]) {
break
}
h.a[i], h.a[j] = h.a[j], h.a[i]
i = j
}
return res
}
var topState []int32
var upR [][]int32
var upL [][]int32
var runStart []int
var capRow []int
func coverLeft(seed, target int) bool {
if seed == target {
return true
}
s := int(topState[seed])
d := target - seed
k := 0
for d > 0 {
if d&1 != 0 {
s = int(upR[k][s])
if s == 0 {
return false
}
}
d >>= 1
k++
}
return runStart[s] <= capRow[target]
}
func coverRight(seed, target int) bool {
if seed == target {
return true
}
s := int(topState[seed])
d := seed - target
k := 0
for d > 0 {
if d&1 != 0 {
s = int(upL[k][s])
if s == 0 {
return false
}
}
d >>= 1
k++
}
return runStart[s] <= capRow[target]
}
func main() {
data, _ := io.ReadAll(os.Stdin)
fs := FastScanner{data: data}
n := fs.nextInt()
m := fs.nextInt()
cols := make([][]int, m+1)
for r := 1; r <= n; r++ {
row := fs.nextBytes()
for c, ch := range row {
if ch == '#' {
cols[c+1] = append(cols[c+1], r)
}
}
}
a := make([]int, m+1)
for i := 1; i <= m; i++ {
a[i] = fs.nextInt()
}
count := make([]int, m+1)
capRow = make([]int, m+1)
req := make([]bool, m+1)
colRunStart := make([]int, m+1)
colRunCnt := make([]int, m+1)
topState = make([]int32, m+1)
runStart = []int{0}
runEnd := []int{0}
for c := 1; c <= m; c++ {
occ := cols[c]
cnt := len(occ)
count[c] = cnt
if a[c] > 0 {
req[c] = true
capRow[c] = occ[cnt-a[c]]
}
if cnt > 0 {
colRunStart[c] = len(runStart)
for i := 0; i < cnt; {
j := i + 1
for j < cnt && occ[j] == occ[j-1]+1 {
j++
}
runStart = append(runStart, occ[i])
runEnd = append(runEnd, occ[j-1])
i = j
}
colRunCnt[c] = len(runStart) - colRunStart[c]
topState[c] = int32(colRunStart[c])
}
}
totalRuns := len(runStart) - 1
nextRight := make([]int32, totalRuns+1)
nextLeft := make([]int32, totalRuns+1)
for c := 1; c < m; c++ {
if count[c] == 0 || count[c+1] == 0 {
continue
}
a0 := colRunStart[c]
ac := colRunCnt[c]
b0 := colRunStart[c+1]
bc := colRunCnt[c+1]
qb := 0
for ia := 0; ia < ac; ia++ {
idA := a0 + ia
s := runStart[idA]
for qb < bc && runEnd[b0+qb] < s {
qb++
}
if qb < bc {
nextRight[idA] = int32(b0 + qb)
}
}
qa := 0
for ib := 0; ib < bc; ib++ {
idB := b0 + ib
s := runStart[idB]
for qa < ac && runEnd[a0+qa] < s {
qa++
}
if qa < ac {
nextLeft[idB] = int32(a0 + qa)
}
}
}
logM := bits.Len(uint(m))
if logM == 0 {
logM = 1
}
upR = make([][]int32, logM)
upL = make([][]int32, logM)
upR[0] = nextRight
upL[0] = nextLeft
for k := 1; k < logM; k++ {
prevR := upR[k-1]
curR := make([]int32, totalRuns+1)
for s := 1; s <= totalRuns; s++ {
x := prevR[s]
if x != 0 {
curR[s] = prevR[int(x)]
}
}
upR[k] = curR
prevL := upL[k-1]
curL := make([]int32, totalRuns+1)
for s := 1; s <= totalRuns; s++ {
x := prevL[s]
if x != 0 {
curL[s] = prevL[int(x)]
}
}
upL[k] = curL
}
Lcov := make([]int, m+1)
Rcov := make([]int, m+1)
far := make([]int, m+1)
dp := make([]int, m+1)
prefixCover := make([]bool, m+1)
suffixCover := make([]bool, m+1)
const INF = int(1e9)
answer := 0
heap := MinHeap{}
for c := 1; c <= m; {
if count[c] == 0 {
c++
continue
}
L := c
hasReqSeg := false
for c <= m && count[c] > 0 {
if req[c] {
hasReqSeg = true
}
c++
}
R := c - 1
if !hasReqSeg {
continue
}
for i := L; i <= R; i++ {
if !req[i] {
continue
}
lo, hi := L, i
for lo < hi {
mid := (lo + hi) >> 1
if coverLeft(mid, i) {
hi = mid
} else {
lo = mid + 1
}
}
Lcov[i] = lo
lo, hi = i, R
for lo < hi {
mid := (lo + hi + 1) >> 1
if coverRight(mid, i) {
lo = mid
} else {
hi = mid - 1
}
}
Rcov[i] = lo
}
bucketMin := make([]int, R-L+1)
for i := range bucketMin {
bucketMin[i] = R + 1
}
for i := L; i <= R; i++ {
if req[i] {
idx := Lcov[i] - L
if Rcov[i] < bucketMin[idx] {
bucketMin[idx] = Rcov[i]
}
}
}
activeMin := R + 1
for l := R; l >= L; l-- {
if l < R {
v := bucketMin[l+1-L]
if v < activeMin {
activeMin = v
}
}
if activeMin <= R {
far[l] = activeMin
} else {
far[l] = R
}
}
minR := R
hasReq := false
for r := L; r <= R; r++ {
prefixCover[r] = !hasReq || r <= minR
if req[r] {
if !hasReq || Rcov[r] < minR {
minR = Rcov[r]
}
hasReq = true
}
}
maxL := L
hasReq = false
for l := R; l >= L; l-- {
suffixCover[l] = !hasReq || l >= maxL
if req[l] {
if !hasReq || Lcov[l] > maxL {
maxL = Lcov[l]
}
hasReq = true
}
}
heap.a = heap.a[:0]
ansSeg := INF
for r := L; r <= R; r++ {
for len(heap.a) > 0 && heap.a[0].far < r {
heap.Pop()
}
best := INF
if prefixCover[r] {
best = 1
}
if len(heap.a) > 0 {
cand := heap.a[0].dp + 1
if cand < best {
best = cand
}
}
dp[r] = best
if suffixCover[r] && best < ansSeg {
ansSeg = best
}
if best < INF && r < R {
heap.Push(Pair{dp: best, far: far[r]})
}
}
answer += ansSeg
}
out := bufio.NewWriterSize(os.Stdout, 1<<20)
fmt.Fprintln(out, answer)
out.Flush()
}