← Home
For problem statement at 0-999/100-199/140-149/149/problemE.txt this is a correct solution, but verifier at 0-999/100-199/140-149/149/verifierE.go ends with All tests passed can you fix the verifier? package main

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

const INF int32 = 1 << 30

type SAM struct {
	next   [][26]int32
	link   []int32
	length []int32
	minp   []int32
	maxp   []int32
	size   int32
	last   int32
}

func NewSAM(n int) *SAM {
	sz := 2*n + 5
	minp := make([]int32, sz)
	for i := range minp {
		minp[i] = INF
	}
	return &SAM{
		next:   make([][26]int32, sz),
		link:   make([]int32, sz),
		length: make([]int32, sz),
		minp:   minp,
		maxp:   make([]int32, sz),
		size:   1,
		last:   1,
	}
}

func (sam *SAM) Extend(ch int, pos int32) {
	sam.size++
	cur := sam.size
	sam.length[cur] = sam.length[sam.last] + 1
	sam.minp[cur] = pos
	sam.maxp[cur] = pos

	p := sam.last
	for p != 0 && sam.next[p][ch] == 0 {
		sam.next[p][ch] = cur
		p = sam.link[p]
	}

	if p == 0 {
		sam.link[cur] = 1
	} else {
		q := sam.next[p][ch]
		if sam.length[p]+1 == sam.length[q] {
			sam.link[cur] = q
		} else {
			sam.size++
			clone := sam.size
			sam.next[clone] = sam.next[q]
			sam.length[clone] = sam.length[p] + 1
			sam.link[clone] = sam.link[q]

			for p != 0 && sam.next[p][ch] == q {
				sam.next[p][ch] = clone
				p = sam.link[p]
			}

			sam.link[q] = clone
			sam.link[cur] = clone
		}
	}

	sam.last = cur
}

func (sam *SAM) Propagate(maxLen int) {
	cnt := make([]int, maxLen+1)
	for i := int32(1); i <= sam.size; i++ {
		cnt[int(sam.length[i])]++
	}
	for i := 1; i <= maxLen; i++ {
		cnt[i] += cnt[i-1]
	}
	order := make([]int32, int(sam.size))
	for i := sam.size; i >= 1; i-- {
		l := int(sam.length[i])
		cnt[l]--
		order[cnt[l]] = i
	}
	for i := len(order) - 1; i >= 0; i-- {
		v := order[i]
		p := sam.link[v]
		if p != 0 {
			if sam.minp[v] < sam.minp[p] {
				sam.minp[p] = sam.minp[v]
			}
			if sam.maxp[v] > sam.maxp[p] {
				sam.maxp[p] = sam.maxp[v]
			}
		}
	}
}

func BuildSAM(s string) *SAM {
	sam := NewSAM(len(s))
	for i := 0; i < len(s); i++ {
		sam.Extend(int(s[i]-'A'), int32(i+1))
	}
	sam.Propagate(len(s))
	return sam
}

func main() {
	in := bufio.NewScanner(os.Stdin)
	in.Buffer(make([]byte, 1024), 1<<20)
	in.Split(bufio.ScanWords)

	in.Scan()
	s := in.Text()
	n := len(s)
	n32 := int32(n)

	samF := BuildSAM(s)

	rs := []byte(s)
	for i, j := 0, n-1; i < j; i, j = i+1, j-1 {
		rs[i], rs[j] = rs[j], rs[i]
	}
	samR := BuildSAM(string(rs))

	in.Scan()
	m, _ := strconv.Atoi(in.Text())

	ans := 0

	for t := 0; t < m; t++ {
		in.Scan()
		p := in.Text()
		L := len(p)

		if L < 2 || L > n {
			continue
		}

		pref := make([]int32, L+1)
		state := int32(1)
		ok := true
		for i := 0; i < L; i++ {
			if ok {
				ns := samF.next[state][int(p[i]-'A')]
				if ns == 0 {
					ok = false
					pref[i+1] = INF
				} else {
					state = ns
					pref[i+1] = samF.minp[state]
				}
			} else {
				pref[i+1] = INF
			}
		}

		suf := make([]int32, L+1)
		state = 1
		ok = true
		for i, l := L-1, 1; i >= 0; i, l = i-1, l+1 {
			if ok {
				ns := samR.next[state][int(p[i]-'A')]
				if ns == 0 {
					ok = false
					suf[l] = 0
				} else {
					state = ns
					suf[l] = n32 - samR.minp[state] + 1
				}
			} else {
				suf[l] = 0
			}
		}

		good := false
		for k := 1; k < L; k++ {
			if pref[k] < suf[L-k] {
				good = true
				break
			}
		}

		if good {
			ans++
		}
	}

	out := bufio.NewWriter(os.Stdout)
	fmt.Fprintln(out, ans)
	out.Flush()
}