← Home
For problem statement at 1000-1999/1100-1199/1160-1169/1168/problemD.txt this is a correct solution, but verifier at 1000-1999/1100-1199/1160-1169/1168/verifierD.go ends with case 1 failed: runtime error: exit status 2
panic: runtime error: index out of range [216] with length 26

goroutine 1 [running]:
main.main.func6(0x2, 0x39)
	/tmp/build-2832650534/solution.go:251 +0x930
main.main()
	/tmp/build-2832650534/solution.go:305 +0xc0c


exit status 1 can you fix the verifier? ```go
package main

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

type SegTree struct {
	tree []int
	lazy []int
}

func newSegTree(n int) SegTree {
	return SegTree{
		tree: make([]int, 4*n),
		lazy: make([]int, 4*n),
	}
}

func (st *SegTree) push(node int) {
	if st.lazy[node] != 0 {
		st.tree[2*node] += st.lazy[node]
		st.lazy[2*node] += st.lazy[node]
		st.tree[2*node+1] += st.lazy[node]
		st.lazy[2*node+1] += st.lazy[node]
		st.lazy[node] = 0
	}
}

func (st *SegTree) add(node, l, r, ql, qr, val int) {
	if ql > r || qr < l {
		return
	}
	if ql <= l && r <= qr {
		st.tree[node] += val
		st.lazy[node] += val
		return
	}
	st.push(node)
	mid := l + (r-l)/2
	st.add(2*node, l, mid, ql, qr, val)
	st.add(2*node+1, mid+1, r, ql, qr, val)
	if st.tree[2*node] > st.tree[2*node+1] {
		st.tree[node] = st.tree[2*node]
	} else {
		st.tree[node] = st.tree[2*node+1]
	}
}

func (st *SegTree) query(node, l, r, ql, qr int) int {
	if ql > r || qr < l {
		return -1e9
	}
	if ql <= l && r <= qr {
		return st.tree[node]
	}
	st.push(node)
	mid := l + (r-l)/2
	left := st.query(2*node, l, mid, ql, qr)
	right := st.query(2*node+1, mid+1, r, ql, qr)
	if left > right {
		return left
	}
	return right
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 1024*1024*10), 1024*1024*10)

	scanString := func() string {
		scanner.Scan()
		return scanner.Text()
	}
	scanInt := func() int {
		scanner.Scan()
		res := 0
		s := scanner.Text()
		for _, c := range s {
			res = res*10 + int(c-'0')
		}
		return res
	}

	n := scanInt()
	q := scanInt()

	parent := make([]int, n+1)
	adj := make([][]int, n+1)
	initialChar := make([]byte, n+1)
	edgeChar := make([]byte, n+1)

	for i := 1; i <= n-1; i++ {
		p := scanInt()
		cStr := scanString()
		u := i + 1
		parent[u] = p
		adj[p] = append(adj[p], u)
		initialChar[u] = cStr[0]
		edgeChar[u] = '?'
	}

	sz := make([]int, n+1)
	depth := make([]int, n+1)
	heavyChild := make([]int, n+1)

	var dfsSz func(int)
	dfsSz = func(u int) {
		sz[u] = 1
		maxSub := 0
		for _, v := range adj[u] {
			depth[v] = depth[u] + 1
			dfsSz(v)
			sz[u] += sz[v]
			if sz[v] > maxSub {
				maxSub = sz[v]
				heavyChild[u] = v
			}
		}
	}
	dfsSz(1)

	hldHead := make([]int, n+1)
	hldPos := make([]int, n+1)
	hldNode := make([]int, n+1)
	hldPosIn := make([]int, n+1)
	hldPosOut := make([]int, n+1)
	hldTimer := 0

	var dfsHld func(int, int)
	dfsHld = func(u, h int) {
		hldHead[u] = h
		hldTimer++
		hldPos[u] = hldTimer
		hldNode[hldTimer] = u
		hldPosIn[u] = hldTimer
		if heavyChild[u] != 0 {
			dfsHld(heavyChild[u], h)
		}
		for _, v := range adj[u] {
			if v != heavyChild[u] {
				dfsHld(v, v)
			}
		}
		hldPosOut[u] = hldTimer
	}
	dfsHld(1, 1)

	leafIn := make([]int, n+1)
	leafOut := make([]int, n+1)
	leafTimer := 0
	possible := true
	D := -1

	var dfsLeaves func(int)
	dfsLeaves = func(u int) {
		isLeaf := true
		leafIn[u] = leafTimer
		for _, v := range adj[u] {
			isLeaf = false
			dfsLeaves(v)
		}
		if isLeaf {
			if D == -1 {
				D = depth[u]
			} else if D != depth[u] {
				possible = false
			}
			leafTimer++
		}
		leafOut[u] = leafTimer - 1
	}
	dfsLeaves(1)

	numLeaves := leafTimer
	var leafST [26]SegTree
	for i := 0; i < 26; i++ {
		leafST[i] = newSegTree(numLeaves)
	}
	globalST := newSegTree(n)

	for i := 1; i <= n; i++ {
		v := hldNode[i]
		globalST.add(1, 1, n, i, i, depth[v]-D)
	}

	updateEdge := func(u int, newC byte) {
		oldC := edgeChar[u]
		if oldC == newC {
			return
		}
		if oldC == '?' {
			globalST.add(1, 1, n, hldPosIn[u], hldPosOut[u], -1)
		} else {
			c := int(oldC - 'a')
			leafST[c].add(1, 0, numLeaves-1, leafIn[u], leafOut[u], -1)
			target := leafST[c].query(1, 0, numLeaves-1, leafIn[u], leafOut[u])

			topNode := u
			curr := parent[u]
			for curr > 0 {
				if leafST[c].query(1, 0, numLeaves-1, leafIn[curr], leafOut[curr]) != target {
					break
				}
				head := hldHead[curr]
				if leafST[c].query(1, 0, numLeaves-1, leafIn[head], leafOut[head]) == target {
					topNode = head
					curr = parent[head]
				} else {
					low := hldPos[head]
					high := hldPos[curr]
					ansPos := high
					for low <= high {
						mid := low + (high-low)/2
						node := hldNode[mid]
						if leafST[c].query(1, 0, numLeaves-1, leafIn[node], leafOut[node]) == target {
							ansPos = mid
							high = mid - 1
						} else {
							low = mid + 1
						}
					}
					topNode = hldNode[ansPos]
					break
				}
			}

			globalST.add(1, 1, n, hldPosIn[u], hldPosOut[u], -1)
			if topNode != u {
				curr = parent[u]
				for depth[curr] >= depth[topNode] {
					head := hldHead[curr]
					if depth[head] < depth[topNode] {
						head = topNode
					}
					globalST.add(1, 1, n, hldPos[head], hldPos[curr], -1)
					curr = parent[head]
					if curr == 0 {
						break
					}
				}
			}
		}

		if newC == '?' {
			globalST.add(1, 1, n, hldPosIn[u], hldPosOut[u], 1)
		} else {
			c := int(newC - 'a')
			target := leafST[c].query(1, 0, numLeaves-1, leafIn[u], leafOut[u])

			topNode := u
			curr := parent[u]
			for curr > 0 {
				if leafST[c].query(1, 0, numLeaves-1, leafIn[curr], leafOut[curr]) != target {
					break
				}
				head := hldHead[curr]
				if leafST[c].query(1, 0, numLeaves-1, leafIn[head], leafOut[head]) == target {
					topNode = head
					curr = parent[head]
				} else {
					low := hldPos[head]
					high := hldPos[curr]
					ansPos := high
					for low <= high {
						mid := low + (high-low)/2
						node := hldNode[mid]
						if leafST[c].query(1, 0, numLeaves-1, leafIn[node], leafOut[node]) == target {
							ansPos = mid
							high = mid - 1
						} else {
							low = mid + 1
						}
					}
					topNode = hldNode[ansPos]
					break
				}
			}

			leafST[c].add(1, 0, numLeaves-1, leafIn[u], leafOut[u], 1)

			globalST.add(1, 1, n, hldPosIn[u], hldPosOut[u], 1)
			if topNode != u {
				curr = parent[u]
				for depth[curr] >= depth[topNode] {
					head := hldHead[curr]
					if depth[head] < depth[topNode] {
						head = topNode
					}
					globalST.add(1, 1, n, hldPos[head], hldPos[curr], 1)
					curr = parent[head]
					if curr == 0 {
						break
					}
				}
			}
		}
		edgeChar[u] = newC
	}

	for i := 2; i <= n; i++ {
		if initialChar[i] != '?' {
			updateEdge(i, initialChar[i])
		}
	}

	for i := 0; i < q; i++ {
		v := scanInt()
		cStr := scanString()
		c := cStr[0]

		updateEdge(v, c)

		if !possible {
			fmt.Println("Fou")
		} else if globalST.query(1, 1, n, 1, n) > 0 {
			fmt.Println("Fou")
		} else {
			S := 0
			var maxC [26]int
			for j := 0; j < 26; j++ {
				maxC[j] = leafST[j].query(1, 0, numLeaves-1, 0, numLeaves-1)
				S += maxC[j]
			}
			ans := 0
			for j := 0; j < 26; j++ {
				f := maxC[j] + D - S
				ans += f * (j + 1)
			}
			fmt.Printf("Shi %d\n", ans)
		}
	}
}
```