← Home
For problem statement at 0-999/300-399/310-319/319/problemD.txt this is a correct solution, but verifier at 0-999/300-399/310-319/319/verifierD.go ends with All tests passed can you fix the verifier? package main

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

type Key struct {
	a uint64
	b uint64
}

const (
	base1 uint64 = 911382323
	base2 uint64 = 972663749
)

var h1, h2, p1, p2 []uint64

func sub(h, p []uint64, l, r int) uint64 {
	return h[r] - h[l-1]*p[r-l+1]
}

func eq(l1, r1, l2, r2 int) bool {
	return sub(h1, p1, l1, r1) == sub(h1, p1, l2, r2) &&
		sub(h2, p2, l1, r1) == sub(h2, p2, l2, r2)
}

func main() {
	in := bufio.NewReaderSize(os.Stdin, 1<<20)
	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	defer out.Flush()

	var s string
	fmt.Fscan(in, &s)
	n := len(s)
	if n == 0 {
		return
	}

	B := int(math.Sqrt(float64(n))) + 1

	h1 = make([]uint64, n+1)
	h2 = make([]uint64, n+1)
	p1 = make([]uint64, n+1)
	p2 = make([]uint64, n+1)
	p1[0], p2[0] = 1, 1
	for i := 1; i <= n; i++ {
		p1[i] = p1[i-1] * base1
		p2[i] = p2[i-1] * base2
	}

	chars := make([]byte, n+1)
	occKey := make([]Key, n+1)
	occ := make(map[Key][]int, n)

	top := 0

	for i := 0; i < n; i++ {
		c := s[i]
		top++
		chars[top] = c
		v := uint64(c-'a'+1)
		h1[top] = h1[top-1]*base1 + v
		h2[top] = h2[top-1]*base2 + v

		var curKey Key
		if top >= B {
			curKey = Key{
				sub(h1, p1, top-B+1, top),
				sub(h2, p2, top-B+1, top),
			}
			occKey[top] = curKey
			occ[curKey] = append(occ[curKey], top)
		}

		found := 0
		lim := top / 2
		small := B
		if lim < small {
			small = lim
		}
		for k := 1; k <= small; k++ {
			if eq(top-2*k+1, top-k, top-k+1, top) {
				found = k
				break
			}
		}

		if found == 0 && top >= B && lim > B {
			lst := occ[curKey]
			for idx := len(lst) - 2; idx >= 0; idx-- {
				j := lst[idx]
				if j*2 < top {
					break
				}
				k := top - j
				if k <= B {
					continue
				}
				if eq(top-2*k+1, top-k, top-k+1, top) {
					found = k
					break
				}
			}
		}

		if found > 0 {
			newTop := top - found
			for t := top; t > newTop; t-- {
				if t >= B {
					k := occKey[t]
					lst := occ[k]
					if len(lst) == 1 {
						delete(occ, k)
					} else {
						occ[k] = lst[:len(lst)-1]
					}
				}
			}
			top = newTop
		}
	}

	out.Write(chars[1 : top+1])
}