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()
}