← Home
For problem statement at 0-999/100-199/150-159/156/problemE.txt this is a correct solution, but verifier at 0-999/100-199/150-159/156/verifierE.go ends with case 48 failed: expected 17
3
37
3 got 17
3
3
3

exit status 1 can you fix the verifier? package main

import (
	"bufio"
	"io"
	"math/bits"
	"os"
	"strconv"
)

type FastScanner struct {
	data []byte
	idx  int
	n    int
}

func NewFastScanner() *FastScanner {
	data, _ := io.ReadAll(os.Stdin)
	return &FastScanner{data: data, n: len(data)}
}

func (fs *FastScanner) skip() {
	for fs.idx < fs.n && fs.data[fs.idx] <= ' ' {
		fs.idx++
	}
}

func (fs *FastScanner) NextUint64() uint64 {
	fs.skip()
	var x uint64
	for fs.idx < fs.n {
		c := fs.data[fs.idx]
		if c < '0' || c > '9' {
			break
		}
		x = x*10 + uint64(c-'0')
		fs.idx++
	}
	return x
}

func (fs *FastScanner) NextString() string {
	fs.skip()
	start := fs.idx
	for fs.idx < fs.n && fs.data[fs.idx] > ' ' {
		fs.idx++
	}
	return string(fs.data[start:fs.idx])
}

type Query struct {
	idx int
	c   uint64
	out int
}

func digitVal(b byte) int {
	if b <= '9' {
		return int(b - '0')
	}
	return int(b-'A') + 10
}

func digitsLen(x, d int) int {
	if x == 0 {
		return 1
	}
	cnt := 0
	for x > 0 {
		cnt++
		x /= d
	}
	return cnt
}

func transformPattern(s string, d, k int, pow []uint32) int {
	l := len(s)
	if l > k {
		extra := l - k
		for i := 0; i < extra; i++ {
			ch := s[i]
			if ch != '?' && ch != '0' {
				return -1
			}
		}
		s = s[extra:]
		l = k
	}
	idx := 0
	pos := k - l
	for i := 0; i < l; i++ {
		ch := s[i]
		if ch == '?' {
			idx += d * int(pow[pos])
		} else {
			idx += digitVal(ch) * int(pow[pos])
		}
		pos++
	}
	return idx
}

func mulMod(a, b, mod uint64) uint64 {
	hi, lo := bits.Mul64(a, b)
	_, rem := bits.Div64(hi, lo, mod)
	return rem
}

func main() {
	primes := []int{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}
	split := 15
	var g1 uint64 = 1
	var g2 uint64 = 1
	for i, p := range primes {
		if i < split {
			g1 *= uint64(p)
		} else {
			g2 *= uint64(p)
		}
	}

	fs := NewFastScanner()

	n := int(fs.NextUint64())
	mods1 := make([]uint64, n)
	mods2 := make([]uint64, n)
	for i := 0; i < n; i++ {
		v := fs.NextUint64()
		mods1[i] = v % g1
		mods2[i] = v % g2
	}

	m := int(fs.NextUint64())

	var ks [17]int
	var powBs [17][]uint32
	var sizes [17]int
	maxS := 0
	maxNum := n - 1
	for d := 2; d <= 16; d++ {
		k := digitsLen(maxNum, d)
		ks[d] = k
		b := d + 1
		pow := make([]uint32, k)
		pow[k-1] = 1
		for i := k - 2; i >= 0; i-- {
			pow[i] = pow[i+1] * uint32(b)
		}
		powBs[d] = pow
		sizes[d] = int(pow[0]) * b
		if sizes[d] > maxS {
			maxS = sizes[d]
		}
	}

	groups := make([][]Query, 17)
	for i := 0; i < m; i++ {
		d := int(fs.NextUint64())
		s := fs.NextString()
		c := fs.NextUint64()
		idx := transformPattern(s, d, ks[d], powBs[d])
		groups[d] = append(groups[d], Query{idx: idx, c: c, out: i})
	}

	answers := make([]int, m)
	h1big := make([]uint64, maxS)
	h2big := make([]uint64, maxS)

	for d := 2; d <= 16; d++ {
		if len(groups[d]) == 0 {
			continue
		}

		k := ks[d]
		powB := powBs[d]
		sz := sizes[d]
		h1 := h1big[:sz]
		h2 := h2big[:sz]

		for i := 0; i < sz; i++ {
			h1[i] = 1
			h2[i] = 1
		}

		exactFrom := make([][]uint32, k+1)
		exactFrom[k] = []uint32{0}
		for pos := k - 1; pos >= 0; pos-- {
			next := exactFrom[pos+1]
			arr := make([]uint32, len(next)*d)
			w := powB[pos]
			idx := 0
			for dig := 0; dig < d; dig++ {
				add := uint32(dig) * w
				for _, off := range next {
					arr[idx] = add + off
					idx++
				}
			}
			exactFrom[pos] = arr
		}

		exactIdx := exactFrom[0]
		for j := 0; j < n; j++ {
			id := exactIdx[j]
			h1[id] = mods1[j]
			h2[id] = mods2[j]
		}

		prefix := []uint32{0}
		for pos := 0; pos < k; pos++ {
			suffix := exactFrom[pos+1]
			w := powB[pos]
			step := int(w)
			dw := int(uint32(d) * w)

			if d == 2 {
				for _, pre := range prefix {
					for _, suf := range suffix {
						base := int(pre + suf)
						t := base + dw
						h1[t] = mulMod(h1[base], h1[base+step], g1)
						h2[t] = mulMod(h2[base], h2[base+step], g2)
					}
				}
			} else {
				for _, pre := range prefix {
					for _, suf := range suffix {
						base := int(pre + suf)
						t := base + dw
						v1 := uint64(1)
						v2 := uint64(1)
						src := base
						for dig := 0; dig < d; dig++ {
							v1 = mulMod(v1, h1[src], g1)
							v2 = mulMod(v2, h2[src], g2)
							src += step
						}
						h1[t] = v1
						h2[t] = v2
					}
				}
			}

			if pos+1 < k {
				nextPrefix := make([]uint32, len(prefix)*(d+1))
				idx := 0
				for _, pre := range prefix {
					for dig := 0; dig <= d; dig++ {
						nextPrefix[idx] = pre + uint32(dig)*w
						idx++
					}
				}
				prefix = nextPrefix
			}
		}

		for _, q := range groups[d] {
			r1, r2 := uint64(1), uint64(1)
			if q.idx >= 0 {
				r1 = h1[q.idx]
				r2 = h2[q.idx]
			}
			ans := -1
			for i, p := range primes {
				pp := uint64(p)
				if i < split {
					if (r1%pp+q.c%pp)%pp == 0 {
						ans = p
						break
					}
				} else {
					if (r2%pp+q.c%pp)%pp == 0 {
						ans = p
						break
					}
				}
			}
			answers[q.out] = ans
		}
	}

	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	buf := make([]byte, 0, 24)
	for i := 0; i < m; i++ {
		buf = strconv.AppendInt(buf[:0], int64(answers[i]), 10)
		out.Write(buf)
		out.WriteByte('\n')
	}
	out.Flush()
}