For problem statement at 2000-2999/2000-2099/2040-2049/2040/problemF.txt this is a correct solution, but verifier at 2000-2999/2000-2099/2040-2049/2040/verifierF.go ends with All tests passed. can you fix the verifier? ```go
package main
import (
"bufio"
"fmt"
"os"
)
const MOD uint32 = 998244353
type Test struct {
a, b, c int
k int
d []int
}
type FastScanner struct {
r *bufio.Reader
}
func NewFastScanner() *FastScanner {
return &FastScanner{r: bufio.NewReaderSize(os.Stdin, 1<<20)}
}
func (fs *FastScanner) NextInt() int {
sign := 1
val := 0
c, err := fs.r.ReadByte()
for (c < '0' || c > '9') && c != '-' {
c, err = fs.r.ReadByte()
if err != nil {
return 0
}
}
if c == '-' {
sign = -1
c, _ = fs.r.ReadByte()
}
for c >= '0' && c <= '9' {
val = val*10 + int(c-'0')
c, err = fs.r.ReadByte()
if err != nil {
break
}
}
return val * sign
}
func mulMod(a, b uint32) uint32 {
return uint32((uint64(a) * uint64(b)) % uint64(MOD))
}
func addMod(a, b uint32) uint32 {
x := a + b
if x >= MOD {
x -= MOD
}
return x
}
func powMod(a uint32, e int64) uint32 {
res := uint32(1)
base := a
for e > 0 {
if (e & 1) != 0 {
res = mulMod(res, base)
}
base = mulMod(base, base)
e >>= 1
}
return res
}
func gcd(a, b int64) int64 {
for b != 0 {
a, b = b, a%b
}
if a < 0 {
return -a
}
return a
}
func lcm(a, b int64) int64 {
return a / gcd(a, b) * b
}
func sieveLinearMuLP(N int) ([]int32, []int8) {
lp := make([]int32, N+1)
mu := make([]int8, N+1)
mu[1] = 1
primes := make([]int32, 0, N/10)
for i := 2; i <= N; i++ {
if lp[i] == 0 {
lp[i] = int32(i)
primes = append(primes, int32(i))
mu[i] = -1
}
for _, p := range primes {
v := int(p) * i
if v > N {
break
}
lp[v] = p
if i%int(p) == 0 {
mu[v] = 0
break
} else {
mu[v] = -mu[i]
}
}
}
return lp, mu
}
func precomputeFact(N int) ([]uint32, []uint32) {
fact := make([]uint32, N+1)
invfact := make([]uint32, N+1)
fact[0] = 1
for i := 1; i <= N; i++ {
fact[i] = mulMod(fact[i-1], uint32(i))
}
invfact[N] = powMod(fact[N], int64(MOD-2))
for i := N - 1; i >= 0; i-- {
invfact[i] = mulMod(invfact[i+1], uint32(i+1))
}
return fact, invfact
}
func factorizeWithLP(n int, lp []int32, primes *[16]int, exps *[16]int) int {
if n <= 1 {
return 0
}
cnt := 0
for n > 1 {
p := int(lp[n])
e := 0
for n%p == 0 {
n /= p
e++
}
primes[cnt] = p
exps[cnt] = e
cnt++
}
return cnt
}
func genDivisorsFromFactors(primes *[16]int, exps *[16]int, cnt int) []int {
res := make([]int, 1, 64)
res[0] = 1
for i := 0; i < cnt; i++ {
p := primes[i]
e := exps[i]
size := len(res)
mul := 1
for j := 1; j <= e; j++ {
mul *= p
for k := 0; k < size; k++ {
res = append(res, res[k]*mul)
}
}
}
return res
}
var gPos []int32
var gDenom []uint32
var gInvfact []uint32
var gCurrentD int
func dfsEnumMul(primes *[16]int, exps *[16]int, cnt int, idx int, curr int) {
if idx == cnt {
p := gPos[curr]
if p > 0 {
ii := int(p - 1)
val := gInvfact[gCurrentD/curr]
gDenom[ii] = mulMod(gDenom[ii], val)
}
return
}
p := primes[idx]
exp := exps[idx]
mul := 1
for i := 0; i <= exp; i++ {
dfsEnumMul(primes, exps, cnt, idx+1, curr*mul)
mul *= p
}
}
func main() {
in := NewFastScanner()
t := in.NextInt()
tests := make([]Test, t)
maxN := 0
for i := 0; i < t; i++ {
a := in.NextInt()
b := in.NextInt()
c := in.NextInt()
k := in.NextInt()
d := make([]int, k)
for j := 0; j < k; j++ {
d[j] = in.NextInt()
}
tests[i] = Test{a: a, b: b, c: c, k: k, d: d}
n := a * b * c
if n > maxN {
maxN = n
}
}
lp, mu := sieveLinearMuLP(maxN)
fact, invfact := precomputeFact(maxN)
// pos array for divisors mapping
pos := make([]int32, maxN+1)
out := bufio.NewWriterSize(os.Stdout, 1<<20)
for _, tt := range tests {
a := tt.a
b := tt.b
c := tt.c
n := a * b * c
// lcm(a,b,c)
l := lcm(int64(a), int64(b))
l = lcm(l, int64(c))
// GCD of all d_i
G := int64(tt.d[0])
for i := 1; i < tt.k; i++ {
G = gcd(G, int64(tt.d[i]))
}
g := int(gcd(G, l))
// divisors of g
var fpr, fex [16]int
cntg := factorizeWithLP(g, lp, &fpr, &fex)
divsG := genDivisorsFromFactors(&fpr, &fex, cntg)
// map divisors to index
for i := 0; i < len(divsG); i++ {
pos[divsG[i]] = int32(i + 1)
}
denom := make([]uint32, len(divsG))
for i := range denom {
denom[i] = 1
}
// set globals for dfs
gPos = pos
gDenom = denom
gInvfact = invfact
// accumulate denominators
for _, dval := range tt.d {
gCurrentD = dval
var p, e [16]int
cnt := factorizeWithLP(dval, lp, &p, &e)
dfsEnumMul(&p, &e, cnt, 0, 1)
}
// Burnside sum over L | g
var S uint32 = 0
// Precompute gcd(a, d), gcd(b, d), gcd(c, d) on the fly per L's divisor
for idx, L := range divsG {
norbits := n / L
F := mulMod(fact[norbits], denom[idx])
// compute W(L) = sum_{d|L} mu(L/d) * gcd(a,d)*gcd(b,d)*gcd(c,d)
var prL, exL [16]int
cntL := factorizeWithLP(L, lp, &prL, &exL)
divsL := genDivisorsFromFactors(&prL, &exL, cntL)
var W int64 = 0
for _, d := range divsL {
tq := L / d
m := int64(mu[tq])
if m == 0 {
continue
}
ga := int(gcd(int64(a), int64(d)))
gb := int(gcd(int64(b), int64(d)))
gc := int(gcd(int64(c), int64(d)))
W += m * int64(ga*gb*gc)
}
// W should be non-negative, but mod anyway
wmod := uint32(((W%int64(MOD))+int64(MOD))%int64(MOD))
term := mulMod(wmod, F)
S = addMod(S, term)
}
invN := powMod(uint32(n), int64(MOD-2))
ans := mulMod(S, invN)
fmt.Fprintln(out, ans)
// clear pos
for _, L := range divsG {
pos[L] = 0
}
}
out.Flush()
}
```