← Home
For problem statement at 1000-1999/1900-1999/1980-1989/1987/problemG2.txt this is a correct solution, but verifier at 1000-1999/1900-1999/1980-1989/1987/verifierG2.go ends with case 1 failed: expected -1 got 3
input:
1
5
4 2 1 5 3
??RL?
exit status 1 can you fix the verifier? package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type State struct {
	cur   int
	cross int
	D     int
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var t int
	fmt.Fscan(reader, &t)

	for tc := 0; tc < t; tc++ {
		var n int
		fmt.Fscan(reader, &n)

		p := make([]int, n+1)
		for i := 1; i <= n; i++ {
			fmt.Fscan(reader, &p[i])
		}

		var sStr string
		fmt.Fscan(reader, &sStr)
		s := make([]byte, n+1)
		for i := 1; i <= n; i++ {
			s[i] = sStr[i-1]
		}

		L := make([]int, n+1)
		R := make([]int, n+1)
		stack := []int{}
		for i := 1; i <= n; i++ {
			for len(stack) > 0 && p[stack[len(stack)-1]] < p[i] {
				stack = stack[:len(stack)-1]
			}
			if len(stack) > 0 {
				L[i] = stack[len(stack)-1]
			} else {
				L[i] = i
			}
			stack = append(stack, i)
		}
		stack = []int{}
		for i := n; i >= 1; i-- {
			for len(stack) > 0 && p[stack[len(stack)-1]] < p[i] {
				stack = stack[:len(stack)-1]
			}
			if len(stack) > 0 {
				R[i] = stack[len(stack)-1]
			} else {
				R[i] = i
			}
			stack = append(stack, i)
		}

		lc := make([]int, n+1)
		rc := make([]int, n+1)
		root := 0
		for i := 1; i <= n; i++ {
			parent := 0
			if L[i] == i && R[i] == i {
				root = i
				continue
			} else if L[i] == i {
				parent = R[i]
			} else if R[i] == i {
				parent = L[i]
			} else {
				if p[L[i]] < p[R[i]] {
					parent = L[i]
				} else {
					parent = R[i]
				}
			}
			if i < parent {
				lc[parent] = i
			} else {
				rc[parent] = i
			}
		}

		getSpine := func(u int, isLeft bool) []int {
			res := []int{}
			if isLeft {
				curr := lc[u]
				for curr != 0 {
					res = append(res, curr)
					curr = rc[curr]
				}
			} else {
				curr := rc[u]
				for curr != 0 {
					res = append(res, curr)
					curr = lc[curr]
				}
			}
			for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
				res[i], res[j] = res[j], res[i]
			}
			return res
		}

		var solveSpine func(spine []int, isLeft bool) []State
		solveSpine = func(spine []int, isLeft bool) []State {
			states := []State{{-1e9, -1e9, 0}}
			for _, x := range spine {
				subSpine := getSpine(x, !isLeft)
				subStates := solveSpine(subSpine, !isLeft)
				if len(subStates) == 0 {
					return []State{}
				}

				newStates := []State{}
				canCross := false
				canUp := false
				if isLeft {
					canCross = s[x] != 'L' && R[x] != x
					canUp = s[x] != 'R' && L[x] != x
				} else {
					canCross = s[x] != 'R' && L[x] != x
					canUp = s[x] != 'L' && R[x] != x
				}

				for _, state := range states {
					for _, sub := range subStates {
						c := state.cur
						if c < 0 {
							c = 0
						}
						sCr := sub.cross
						if sCr < 0 {
							sCr = 0
						}
						maxUpX := c
						if sCr > maxUpX {
							maxUpX = sCr
						}
						maxUpX++

						diamX := c + sCr
						DNew := state.D
						if sub.D > DNew {
							DNew = sub.D
						}
						if diamX > DNew {
							DNew = diamX
						}

						if canCross {
							nxtMaxCross := state.cross
							if maxUpX > nxtMaxCross {
								nxtMaxCross = maxUpX
							}
							nxtCurUp := sub.cur
							nxtD := DNew
							if state.cross > -1e8 {
								if state.cross+maxUpX > nxtD {
									nxtD = state.cross + maxUpX
								}
							}
							newStates = append(newStates, State{nxtCurUp, nxtMaxCross, nxtD})
						}

						if canUp {
							nxtMaxCross := state.cross
							nxtCurUp := maxUpX
							if sub.cur > nxtCurUp {
								nxtCurUp = sub.cur
							}
							nxtD := DNew
							if sub.cur > -1e8 && maxUpX > -1e8 {
								if sub.cur+maxUpX > nxtD {
									nxtD = sub.cur + maxUpX
								}
							}
							newStates = append(newStates, State{nxtCurUp, nxtMaxCross, nxtD})
						}
					}
				}

				if len(newStates) == 0 {
					return []State{}
				}

				sort.Slice(newStates, func(i, j int) bool {
					if newStates[i].cur != newStates[j].cur {
						return newStates[i].cur > newStates[j].cur
					}
					if newStates[i].cross != newStates[j].cross {
						return newStates[i].cross > newStates[j].cross
					}
					return newStates[i].D > newStates[j].D
				})

				filtered := []State{}
				for _, s := range newStates {
					dominated := false
					for _, r := range filtered {
						if r.cross >= s.cross && r.D >= s.D {
							dominated = true
							break
						}
					}
					if !dominated {
						filtered = append(filtered, s)
					}
				}
				states = filtered
			}
			return states
		}

		leftSpine := getSpine(root, true)
		leftStates := solveSpine(leftSpine, true)
		rightSpine := getSpine(root, false)
		rightStates := solveSpine(rightSpine, false)

		if len(leftStates) == 0 || len(rightStates) == 0 {
			fmt.Fprintln(writer, -1)
			continue
		}

		ans := 0
		for _, ls := range leftStates {
			for _, rs := range rightStates {
				cand := ls.D
				if rs.D > cand {
					cand = rs.D
				}
				paths := []int{}
				if ls.cross > 0 {
					paths = append(paths, ls.cross)
				} else {
					paths = append(paths, 0)
				}
				if ls.cur > 0 {
					paths = append(paths, ls.cur)
				} else {
					paths = append(paths, 0)
				}
				if rs.cross > 0 {
					paths = append(paths, rs.cross)
				} else {
					paths = append(paths, 0)
				}
				if rs.cur > 0 {
					paths = append(paths, rs.cur)
				} else {
					paths = append(paths, 0)
				}
				sort.Slice(paths, func(i, j int) bool {
					return paths[i] > paths[j]
				})
				if paths[0]+paths[1] > cand {
					cand = paths[0] + paths[1]
				}
				if cand > ans {
					ans = cand
				}
			}
		}

		fmt.Fprintln(writer, ans)
	}
}