← Home
For problem statement at 0-999/500-599/580-589/587/problemF.txt this is a correct solution, but verifier at 0-999/500-599/580-589/587/verifierF.go ends with All tests passed can you fix the verifier? package main

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

type TrieNode struct {
	child [26]int
	fail  int
}

type Query struct {
	l, r, k, idx int
}

type LightQuery struct {
	idx  int
	sign int
	k    int
}

func readWord(r *bufio.Reader) string {
	var res []byte
	for {
		b, err := r.ReadByte()
		if err != nil {
			break
		}
		if b > ' ' {
			res = append(res, b)
			break
		}
	}
	if len(res) == 0 {
		return ""
	}
	for {
		b, err := r.ReadByte()
		if err != nil {
			break
		}
		if b <= ' ' {
			break
		}
		res = append(res, b)
	}
	return string(res)
}

func nextInt(r *bufio.Reader) int {
	res := 0
	sign := 1
	for {
		b, err := r.ReadByte()
		if err != nil {
			break
		}
		if b == '-' {
			sign = -1
			break
		}
		if b >= '0' && b <= '9' {
			res = int(b - '0')
			break
		}
	}
	for {
		b, err := r.ReadByte()
		if err != nil || b < '0' || b > '9' {
			break
		}
		res = res*10 + int(b-'0')
	}
	return res * sign
}

func main() {
	reader := bufio.NewReaderSize(os.Stdin, 65536)
	n := nextInt(reader)
	if n == 0 {
		return
	}
	q := nextInt(reader)

	strs := make([]string, n+1)
	pos := make([]int, n+1)
	nodes := make([]TrieNode, 1, 100005)

	for i := 1; i <= n; i++ {
		strs[i] = readWord(reader)
		u := 0
		s := strs[i]
		for j := 0; j < len(s); j++ {
			c := s[j] - 'a'
			if nodes[u].child[c] == 0 {
				nodes[u].child[c] = len(nodes)
				nodes = append(nodes, TrieNode{})
			}
			u = nodes[u].child[c]
		}
		pos[i] = u
	}

	queue := make([]int, 0, len(nodes))
	for c := 0; c < 26; c++ {
		if nodes[0].child[c] != 0 {
			queue = append(queue, nodes[0].child[c])
		}
	}

	for i := 0; i < len(queue); i++ {
		u := queue[i]
		for c := 0; c < 26; c++ {
			v := nodes[u].child[c]
			if v != 0 {
				nodes[v].fail = nodes[nodes[u].fail].child[c]
				queue = append(queue, v)
			} else {
				nodes[u].child[c] = nodes[nodes[u].fail].child[c]
			}
		}
	}

	failAdj := make([][]int, len(nodes))
	for i := 1; i < len(nodes); i++ {
		failAdj[nodes[i].fail] = append(failAdj[nodes[i].fail], i)
	}

	in := make([]int, len(nodes))
	out := make([]int, len(nodes))
	postOrder := make([]int, 0, len(nodes))
	timer := 1

	var dfs func(int)
	dfs = func(u int) {
		in[u] = timer
		timer++
		for _, v := range failAdj[u] {
			dfs(v)
		}
		out[u] = timer
		postOrder = append(postOrder, u)
	}
	dfs(0)

	const B = 316

	heavyQueries := make(map[int][]Query)
	lightQueries := make([][]LightQuery, n+1)

	for i := 0; i < q; i++ {
		l := nextInt(reader)
		r := nextInt(reader)
		k := nextInt(reader)
		if len(strs[k]) > B {
			heavyQueries[k] = append(heavyQueries[k], Query{l, r, k, i})
		} else {
			lightQueries[r] = append(lightQueries[r], LightQuery{i, 1, k})
			lightQueries[l-1] = append(lightQueries[l-1], LightQuery{i, -1, k})
		}
	}

	ans := make([]int64, q)
	count := make([]int64, len(nodes))
	pref := make([]int64, n+1)

	for k, queries := range heavyQueries {
		for i := range count {
			count[i] = 0
		}
		u := 0
		s := strs[k]
		for j := 0; j < len(s); j++ {
			u = nodes[u].child[s[j]-'a']
			count[u]++
		}
		for _, u := range postOrder {
			if u != 0 {
				count[nodes[u].fail] += count[u]
			}
		}
		for i := 1; i <= n; i++ {
			pref[i] = pref[i-1] + count[pos[i]]
		}
		for _, q := range queries {
			ans[q.idx] = pref[q.r] - pref[q.l-1]
		}
	}

	bit := make([]int64, len(nodes)+2)
	add := func(idx int, val int64) {
		for ; idx < len(bit); idx += idx & -idx {
			bit[idx] += val
		}
	}
	query := func(idx int) int64 {
		var sum int64 = 0
		for ; idx > 0; idx -= idx & -idx {
			sum += bit[idx]
		}
		return sum
	}

	for i := 0; i <= n; i++ {
		if i > 0 {
			u := pos[i]
			add(in[u], 1)
			add(out[u], -1)
		}
		for _, lq := range lightQueries[i] {
			var sum int64 = 0
			u := 0
			s := strs[lq.k]
			for j := 0; j < len(s); j++ {
				u = nodes[u].child[s[j]-'a']
				sum += query(in[u])
			}
			if lq.sign == 1 {
				ans[lq.idx] += sum
			} else {
				ans[lq.idx] -= sum
			}
		}
	}

	outWriter := bufio.NewWriter(os.Stdout)
	for i := 0; i < q; i++ {
		outWriter.WriteString(strconv.FormatInt(ans[i], 10))
		outWriter.WriteByte('\n')
	}
	outWriter.Flush()
}