← Home
For problem statement at 1000-1999/1000-1099/1030-1039/1034/problemC.txt this is a correct solution, but verifier at 1000-1999/1000-1099/1030-1039/1034/verifierC.go ends with All tests passed can you fix the verifier? package main

import (
	"fmt"
	"io"
	"os"
	"sort"
)

type Divisor struct {
	val  uint64
	mask uint64
}

func gcd(a, b uint64) uint64 {
	for b != 0 {
		a, b = b, a%b
	}
	return a
}

func getBits(e int) int {
	b := 1
	for (1 << (b - 1)) <= e {
		b++
	}
	return b
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	var pos int
	readInt := func() int {
		for pos < len(data) && (data[pos] < '0' || data[pos] > '9') {
			pos++
		}
		if pos >= len(data) {
			return 0
		}
		res := 0
		for pos < len(data) && data[pos] >= '0' && data[pos] <= '9' {
			res = res*10 + int(data[pos]-'0')
			pos++
		}
		return res
	}

	n := readInt()
	if n == 0 {
		return
	}

	a := make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = readInt()
	}

	pArr := make([]int, n-1)
	for i := 0; i < n-1; i++ {
		pArr[i] = readInt()
	}

	w := make([]uint64, n+1)
	for i := 1; i <= n; i++ {
		w[i] = uint64(a[i-1])
	}
	for i := n; i >= 2; i-- {
		p := pArr[i-2]
		w[p] += w[i]
	}

	W := w[1]

	var primes []uint64
	var exponents []int
	tmp := W
	for i := uint64(2); i*i <= tmp; i++ {
		if tmp%i == 0 {
			primes = append(primes, i)
			c := 0
			for tmp%i == 0 {
				c++
				tmp /= i
			}
			exponents = append(exponents, c)
		}
	}
	if tmp > 1 {
		primes = append(primes, tmp)
		exponents = append(exponents, 1)
	}

	var widths []int
	var shifts []int
	shift := 0
	BorrowBits := uint64(0)
	for i := 0; i < len(primes); i++ {
		wBits := getBits(exponents[i])
		widths = append(widths, wBits)
		shifts = append(shifts, shift)
		BorrowBits |= uint64(1) << (shift + wBits - 1)
		shift += wBits
	}

	var D []Divisor
	var dfs func(idx int, currentVal uint64, currentMask uint64)
	dfs = func(idx int, currentVal uint64, currentMask uint64) {
		if idx == len(primes) {
			D = append(D, Divisor{val: currentVal, mask: currentMask})
			return
		}
		p := primes[idx]
		val := currentVal
		for c := 0; c <= exponents[idx]; c++ {
			dfs(idx+1, val, currentMask|(uint64(c)<<shifts[idx]))
			if c < exponents[idx] {
				val *= p
			}
		}
	}
	dfs(0, 1, 0)

	sort.Slice(D, func(i, j int) bool {
		return D[i].val < D[j].val
	})

	A := make([]int, len(D))
	for i := 1; i <= n; i++ {
		g := gcd(w[i], W)
		idx := sort.Search(len(D), func(j int) bool { return D[j].val >= g })
		if idx < len(D) && D[idx].val == g {
			A[idx]++
		}
	}

	for r := 0; r < len(primes); r++ {
		p := primes[r]
		for i := len(D) - 1; i >= 0; i-- {
			mask := D[i].mask
			c := int((mask >> shifts[r]) & ((1 << (widths[r] - 1)) - 1))
			if c < exponents[r] {
				target := D[i].val * p
				idx := sort.Search(len(D), func(j int) bool { return D[j].val >= target })
				if idx < len(D) && D[idx].val == target {
					A[i] += A[idx]
				}
			}
		}
	}

	var V []Divisor
	for i := 0; i < len(D); i++ {
		if uint64(A[i]) == W/D[i].val {
			V = append(V, D[i])
		}
	}

	dp := make([]uint32, len(V))
	if len(V) > 0 {
		dp[len(V)-1] = 1
	}

	ans := uint32(0)
	for i := len(V) - 1; i >= 0; i-- {
		dpi := dp[i]
		if dpi == 0 {
			continue
		}
		ans = (ans + dpi) % 1000000007
		mi := V[i].mask
		for j := i - 1; j >= 0; j-- {
			diff := (mi | BorrowBits) - V[j].mask
			if diff&BorrowBits == BorrowBits {
				dp[j] += dpi
				if dp[j] >= 1000000007 {
					dp[j] -= 1000000007
				}
			}
		}
	}

	fmt.Println(ans)
}