For problem statement at 0-999/0-99/30-39/30/problemE.txt this is a correct solution, but verifier at 0-999/0-99/30-39/30/verifierE.go ends with case 20 failed: invalid segments
input:caccacb
exit status 1 can you fix the verifier? package main
import (
"bufio"
"fmt"
"os"
)
func buildSA(s []int) []int {
n := len(s)
p := make([]int, n)
c := make([]int, n)
cntSize := n
if cntSize < 28 {
cntSize = 28
}
cnt := make([]int, cntSize)
for i := 0; i < n; i++ {
cnt[s[i]]++
}
for i := 1; i < cntSize; i++ {
cnt[i] += cnt[i-1]
}
for i := 0; i < n; i++ {
x := s[i]
cnt[x]--
p[cnt[x]] = i
}
classes := 1
c[p[0]] = 0
for i := 1; i < n; i++ {
if s[p[i]] != s[p[i-1]] {
classes++
}
c[p[i]] = classes - 1
}
pn := make([]int, n)
cn := make([]int, n)
for h := 0; (1 << h) < n; h++ {
shift := 1 << h
for i := 0; i < n; i++ {
pn[i] = p[i] - shift
if pn[i] < 0 {
pn[i] += n
}
}
for i := 0; i < classes; i++ {
cnt[i] = 0
}
for i := 0; i < n; i++ {
cnt[c[pn[i]]]++
}
for i := 1; i < classes; i++ {
cnt[i] += cnt[i-1]
}
for i := n - 1; i >= 0; i-- {
x := pn[i]
cl := c[x]
cnt[cl]--
p[cnt[cl]] = x
}
classes = 1
cn[p[0]] = 0
for i := 1; i < n; i++ {
cur := p[i]
prev := p[i-1]
cur2 := cur + shift
if cur2 >= n {
cur2 -= n
}
prev2 := prev + shift
if prev2 >= n {
prev2 -= n
}
if c[cur] != c[prev] || c[cur2] != c[prev2] {
classes++
}
cn[cur] = classes - 1
}
copy(c, cn)
}
return p
}
func buildLCP(s []int, sa []int) []int {
n := len(s)
rank := make([]int, n)
for i, p := range sa {
rank[p] = i
}
lcp := make([]int, n-1)
k := 0
for i := 0; i < n; i++ {
r := rank[i]
if r == n-1 {
k = 0
continue
}
j := sa[r+1]
for i+k < n && j+k < n && s[i+k] == s[j+k] {
k++
}
lcp[r] = k
if k > 0 {
k--
}
}
return lcp
}
func manacherOdd(s string) []int {
n := len(s)
d1 := make([]int, n)
l, r := 0, -1
for i := 0; i < n; i++ {
k := 1
if i <= r {
mirror := l + r - i
if d1[mirror] < r-i+1 {
k = d1[mirror]
} else {
k = r - i + 1
}
}
for i-k >= 0 && i+k < n && s[i-k] == s[i+k] {
k++
}
d1[i] = k
if i+k-1 > r {
l = i - k + 1
r = i + k - 1
}
}
return d1
}
func main() {
in := bufio.NewReaderSize(os.Stdin, 1<<20)
var s string
fmt.Fscan(in, &s)
n := len(s)
rev := make([]byte, n)
for i := 0; i < n; i++ {
rev[i] = s[n-1-i]
}
arr := make([]int, 0, 2*n+2)
for i := 0; i < n; i++ {
arr = append(arr, int(s[i]-'a')+1)
}
arr = append(arr, 27)
for i := 0; i < n; i++ {
arr = append(arr, int(rev[i]-'a')+1)
}
arr = append(arr, 0)
sa := buildSA(arr)
lcp := buildLCP(arr, sa)
d1 := manacherOdd(s)
lg := make([]int, n+1)
for i := 2; i <= n; i++ {
lg[i] = lg[i/2] + 1
}
K := lg[n] + 1
st := make([][]int, K)
st[0] = make([]int, n)
copy(st[0], d1)
for k := 1; k < K; k++ {
span := 1 << k
half := span >> 1
m := n - span + 1
row := make([]int, m)
prev := st[k-1]
for i := 0; i < m; i++ {
if prev[i] > prev[i+half] {
row[i] = prev[i]
} else {
row[i] = prev[i+half]
}
}
st[k] = row
}
rangeMax := func(l, r int) int {
if l > r {
return 0
}
k := lg[r-l+1]
a := st[k][l]
b := st[k][r-(1<<k)+1]
if a > b {
return a
}
return b
}
size := 1
for size < n {
size <<= 1
}
seg := make([]int, size<<1)
for i := 0; i < n; i++ {
seg[size+i] = d1[i]
}
for i := size - 1; i >= 1; i-- {
if seg[i<<1] > seg[i<<1|1] {
seg[i] = seg[i<<1]
} else {
seg[i] = seg[i<<1|1]
}
}
var findFirst func(node, nl, nr, l, r, thr int) int
findFirst = func(node, nl, nr, l, r, thr int) int {
if l > nr || r < nl || seg[node] <= thr {
return -1
}
if nl == nr {
return nl
}
mid := (nl + nr) >> 1
res := findFirst(node<<1, nl, mid, l, r, thr)
if res != -1 {
return res
}
return findFirst(node<<1|1, mid+1, nr, l, r, thr)
}
bestPal := func(L, R int) (int, int) {
lo, hi := 0, (R-L)/2
for lo < hi {
mid := (lo + hi + 1) >> 1
if rangeMax(L-1+mid, R-1-mid) > mid {
lo = mid
} else {
hi = mid - 1
}
}
t := lo
c := findFirst(1, 0, size-1, L-1+t, R-1-t, t)
return 2*t + 1, c + 1 - t
}
const INF = int(1e9)
m := len(sa)
capNodes := 2*m + 5
depth := make([]int, 0, capNodes)
parent := make([]int, 0, capNodes)
leafPos := make([]int, 0, capNodes)
first := make([]int, 0, capNodes)
last := make([]int, 0, capNodes)
prevSib := make([]int, 0, capNodes)
nextSib := make([]int, 0, capNodes)
minS := make([]int, 0, capNodes)
minT := make([]int, 0, capNodes)
newNode := func(dep, pos int) int {
id := len(depth)
depth = append(depth, dep)
parent = append(parent, -1)
leafPos = append(leafPos, pos)
first = append(first, -1)
last = append(last, -1)
prevSib = append(prevSib, -1)
nextSib = append(nextSib, -1)
minS = append(minS, INF)
minT = append(minT, INF)
return id
}
appendChild := func(p, ch int) {
parent[ch] = p
prevSib[ch] = last[p]
nextSib[ch] = -1
if last[p] != -1 {
nextSib[last[p]] = ch
} else {
first[p] = ch
}
last[p] = ch
}
detachLast := func(p int) int {
ch := last[p]
pr := prevSib[ch]
if pr != -1 {
nextSib[pr] = -1
} else {
first[p] = -1
}
last[p] = pr
parent[ch] = -1
prevSib[ch] = -1
nextSib[ch] = -1
return ch
}
root := newNode(0, -1)
stack := []int{root}
for i, pos := range sa {
l := 0
if i > 0 {
l = lcp[i-1]
}
for depth[stack[len(stack)-1]] > l {
stack = stack[:len(stack)-1]
}
if depth[stack[len(stack)-1]] < l {
p := stack[len(stack)-1]
v := newNode(l, -1)
ch := detachLast(p)
appendChild(p, v)
appendChild(v, ch)
stack = append(stack, v)
}
leaf := newNode(0, pos)
appendChild(stack[len(stack)-1], leaf)
}
order := make([]int, 0, len(depth))
stk := []int{root}
for len(stk) > 0 {
v := stk[len(stk)-1]
stk = stk[:len(stk)-1]
order = append(order, v)
for ch := first[v]; ch != -1; ch = nextSib[ch] {
stk = append(stk, ch)
}
}
for i := len(order) - 1; i >= 0; i-- {
v := order[i]
if first[v] == -1 {
pos := leafPos[v]
if pos >= 0 && pos < n {
minS[v] = pos + 1
} else if pos > n && pos < 2*n+1 {
minT[v] = pos - n
}
} else {
ms, mt := INF, INF
for ch := first[v]; ch != -1; ch = nextSib[ch] {
if minS[ch] < ms {
ms = minS[ch]
}
if minT[ch] < mt {
mt = minT[ch]
}
}
minS[v] = ms
minT[v] = mt
}
}
bestTotal, bestMidStart := bestPal(1, n)
bestMidLen := bestTotal
bestK := 1
bestPrefixStart := 0
bestOuterLen := 0
bestSuffixStart := 0
for v := 1; v < len(depth); v++ {
if first[v] == -1 || depth[v] == 0 || minS[v] == INF || minT[v] == INF {
continue
}
A := minS[v]
C := n - minT[v] + 1
limit := (C - A) / 2
d := depth[v]
if limit < d {
d = limit
}
pd := 0
if parent[v] != -1 {
pd = depth[parent[v]]
}
if d <= pd || d <= 0 {
continue
}
L := A + d
R := C - d
palLen, palStart := bestPal(L, R)
total := 2*d + palLen
if total > bestTotal {
bestTotal = total
bestK = 3
bestPrefixStart = A
bestOuterLen = d
bestMidStart = palStart
bestMidLen = palLen
bestSuffixStart = R + 1
}
}
out := bufio.NewWriterSize(os.Stdout, 1<<20)
defer out.Flush()
fmt.Fprintln(out, bestK)
if bestK == 1 {
fmt.Fprintln(out, bestMidStart, bestMidLen)
} else {
fmt.Fprintln(out, bestPrefixStart, bestOuterLen)
fmt.Fprintln(out, bestMidStart, bestMidLen)
fmt.Fprintln(out, bestSuffixStart, bestOuterLen)
}
}