← Home
For problem statement at 0-999/600-699/660-669/666/problemE.txt this is a correct solution, but verifier at 0-999/600-699/660-669/666/verifierE.go ends with case 27 failed
input:
baca
1
ca
2
1 1 2 4
1 1 1 2

exp:
1 1
1 0
---
got:
1 0
1 0
exit status 1 can you fix the verifier? package main

import (
	"bufio"
	"os"
	"strconv"
)

const MAX_SEG_NODES = 8000005
const MAX_SAM_NODES = 200005

var ls [MAX_SEG_NODES]int32
var rs [MAX_SEG_NODES]int32
var maxVal [MAX_SEG_NODES]int32
var maxIdx [MAX_SEG_NODES]int32
var segNodes int32 = 0

func allocNode() int32 {
	segNodes++
	return segNodes
}

func pushUp(u int32) {
	if maxVal[ls[u]] > maxVal[rs[u]] {
		maxVal[u] = maxVal[ls[u]]
		maxIdx[u] = maxIdx[ls[u]]
	} else if maxVal[ls[u]] < maxVal[rs[u]] {
		maxVal[u] = maxVal[rs[u]]
		maxIdx[u] = maxIdx[rs[u]]
	} else {
		maxVal[u] = maxVal[ls[u]]
		if maxIdx[ls[u]] <= maxIdx[rs[u]] {
			maxIdx[u] = maxIdx[ls[u]]
		} else {
			maxIdx[u] = maxIdx[rs[u]]
		}
	}
}

func insert(u *int32, l, r, pos int32) {
	if *u == 0 {
		*u = allocNode()
	}
	if l == r {
		maxVal[*u]++
		maxIdx[*u] = l
		return
	}
	mid := (l + r) / 2
	if pos <= mid {
		insert(&ls[*u], l, mid, pos)
	} else {
		insert(&rs[*u], mid+1, r, pos)
	}
	pushUp(*u)
}

func merge(u, v int32, l, r int32) int32 {
	if u == 0 || v == 0 {
		return u ^ v
	}
	newNode := allocNode()
	if l == r {
		maxVal[newNode] = maxVal[u] + maxVal[v]
		maxIdx[newNode] = l
		return newNode
	}
	mid := (l + r) / 2
	ls[newNode] = merge(ls[u], ls[v], l, mid)
	rs[newNode] = merge(rs[u], rs[v], mid+1, r)
	pushUp(newNode)
	return newNode
}

func querySeg(u int32, l, r, ql, qr int32) (int32, int32) {
	if u == 0 {
		return 0, 0
	}
	if ql <= l && r <= qr {
		return maxVal[u], maxIdx[u]
	}
	mid := (l + r) / 2
	var ansVal, ansIdx int32 = -1, -1
	if ql <= mid {
		v, idx := querySeg(ls[u], l, mid, ql, qr)
		if v > ansVal || (v == ansVal && idx < ansIdx) {
			ansVal, ansIdx = v, idx
		}
	}
	if qr > mid {
		v, idx := querySeg(rs[u], mid+1, r, ql, qr)
		if v > ansVal || (v == ansVal && idx < ansIdx) {
			ansVal, ansIdx = v, idx
		}
	}
	return ansVal, ansIdx
}

var samNext [MAX_SAM_NODES][26]int32
var samLink [MAX_SAM_NODES]int32
var samLen [MAX_SAM_NODES]int32
var root [MAX_SAM_NODES]int32
var head [MAX_SAM_NODES]int32
var nxt [MAX_SAM_NODES]int32
var up [MAX_SAM_NODES][18]int32
var samNodes int32 = 0

func allocSamNode() int32 {
	samNodes++
	samLink[samNodes] = 0
	return samNodes
}

func initSAM() {
	allocSamNode()
}

func extend(c int32, last int32) int32 {
	if samNext[last][c] != 0 {
		q := samNext[last][c]
		if samLen[q] == samLen[last]+1 {
			return q
		}
		clone := allocSamNode()
		samLen[clone] = samLen[last] + 1
		for i := int32(0); i < 26; i++ {
			samNext[clone][i] = samNext[q][i]
		}
		samLink[clone] = samLink[q]
		samLink[q] = clone
		for p := last; p != 0 && samNext[p][c] == q; p = samLink[p] {
			samNext[p][c] = clone
		}
		return clone
	}
	cur := allocSamNode()
	samLen[cur] = samLen[last] + 1
	p := last
	for p != 0 && samNext[p][c] == 0 {
		samNext[p][c] = cur
		p = samLink[p]
	}
	if p == 0 {
		samLink[cur] = 1
	} else {
		q := samNext[p][c]
		if samLen[q] == samLen[p]+1 {
			samLink[cur] = q
		} else {
			clone := allocSamNode()
			samLen[clone] = samLen[p] + 1
			for i := int32(0); i < 26; i++ {
				samNext[clone][i] = samNext[q][i]
			}
			samLink[clone] = samLink[q]
			samLink[q] = clone
			samLink[cur] = clone
			for p != 0 && samNext[p][c] == q {
				samNext[p][c] = clone
				p = samLink[p]
			}
		}
	}
	return cur
}

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

	if !scanner.Scan() {
		return
	}
	s := scanner.Text()

	if !scanner.Scan() {
		return
	}
	m, _ := strconv.Atoi(scanner.Text())

	initSAM()
	for i := 1; i <= m; i++ {
		if !scanner.Scan() {
			return
		}
		text := scanner.Text()
		last := int32(1)
		for j := 0; j < len(text); j++ {
			last = extend(int32(text[j]-'a'), last)
			insert(&root[last], 1, int32(m), int32(i))
		}
	}

	maxL := int32(0)
	for i := int32(2); i <= samNodes; i++ {
		if samLen[i] > maxL {
			maxL = samLen[i]
		}
	}
	for i := int32(0); i <= maxL; i++ {
		head[i] = 0
	}
	for i := int32(2); i <= samNodes; i++ {
		nxt[i] = head[samLen[i]]
		head[samLen[i]] = i
	}
	for l := maxL; l >= 1; l-- {
		for u := head[l]; u != 0; u = nxt[u] {
			p := samLink[u]
			if p != 0 {
				root[p] = merge(root[p], root[u], 1, int32(m))
			}
		}
	}

	for i := int32(1); i <= samNodes; i++ {
		up[i][0] = samLink[i]
	}
	for j := 1; j < 18; j++ {
		for i := int32(1); i <= samNodes; i++ {
			if up[i][j-1] != 0 {
				up[i][j] = up[up[i][j-1]][j-1]
			} else {
				up[i][j] = 0
			}
		}
	}

	matchNode := make([]int32, len(s))
	matchLen := make([]int32, len(s))
	cur := int32(1)
	l := int32(0)
	for i := 0; i < len(s); i++ {
		c := int32(s[i] - 'a')
		for cur != 0 && samNext[cur][c] == 0 {
			cur = samLink[cur]
			if cur != 0 {
				l = samLen[cur]
			} else {
				l = 0
			}
		}
		if cur == 0 {
			cur = 1
			l = 0
		} else {
			cur = samNext[cur][c]
			l++
		}
		matchNode[i] = cur
		matchLen[i] = l
	}

	if !scanner.Scan() {
		return
	}
	q, _ := strconv.Atoi(scanner.Text())

	out := bufio.NewWriterSize(os.Stdout, 1024*1024)
	defer out.Flush()

	for i := 0; i < q; i++ {
		scanner.Scan()
		l_text, _ := strconv.Atoi(scanner.Text())
		scanner.Scan()
		r_text, _ := strconv.Atoi(scanner.Text())
		scanner.Scan()
		pl, _ := strconv.Atoi(scanner.Text())
		scanner.Scan()
		pr, _ := strconv.Atoi(scanner.Text())

		pl--
		pr--
		qLen := int32(pr - pl + 1)
		if matchLen[pr] < qLen {
			out.WriteString(strconv.Itoa(l_text) + " 0\n")
			continue
		}
		v := matchNode[pr]
		for j := 17; j >= 0; j-- {
			p := up[v][j]
			if p != 0 && samLen[p] >= qLen {
				v = p
			}
		}
		val, idx := querySeg(root[v], 1, int32(m), int32(l_text), int32(r_text))
		if val == 0 {
			idx = int32(l_text)
		}
		out.WriteString(strconv.Itoa(int(idx)) + " " + strconv.Itoa(int(val)) + "\n")
	}
}