← Home
For problem statement at 1000-1999/1000-1099/1010-1019/1016/problemG.txt this is a correct solution, but verifier at 1000-1999/1000-1099/1010-1019/1016/verifierG.go ends with All tests passed can you fix the verifier? package main

import (
	"io"
	"os"
	"strconv"
)

type Scanner struct {
	data []byte
	idx  int
}

func NewScanner() *Scanner {
	data, _ := io.ReadAll(os.Stdin)
	return &Scanner{data: data}
}

func (s *Scanner) NextUint64() uint64 {
	n := len(s.data)
	for s.idx < n && s.data[s.idx] <= ' ' {
		s.idx++
	}
	var v uint64
	for s.idx < n && s.data[s.idx] > ' ' {
		v = v*10 + uint64(s.data[s.idx]-'0')
		s.idx++
	}
	return v
}

var smallPrimes = []uint64{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}
var rngState uint64 = 88172645463393265

func nextRand() uint64 {
	rngState += 0x9e3779b97f4a7c15
	z := rngState
	z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9
	z = (z ^ (z >> 27)) * 0x94d049bb133111eb
	return z ^ (z >> 31)
}

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

func mulMod(a, b, mod uint64) uint64 {
	var res uint64
	for b > 0 {
		if b&1 == 1 {
			res += a
			if res >= mod {
				res -= mod
			}
		}
		a += a
		if a >= mod {
			a -= mod
		}
		b >>= 1
	}
	return res
}

func powMod(a, e, mod uint64) uint64 {
	res := uint64(1)
	for e > 0 {
		if e&1 == 1 {
			res = mulMod(res, a, mod)
		}
		a = mulMod(a, a, mod)
		e >>= 1
	}
	return res
}

func isPrime(n uint64) bool {
	if n < 2 {
		return false
	}
	for _, p := range smallPrimes {
		if n%p == 0 {
			return n == p
		}
	}
	d := n - 1
	s := 0
	for d&1 == 0 {
		d >>= 1
		s++
	}
	bases := []uint64{2, 325, 9375, 28178, 450775, 9780504, 1795265022}
	for _, a := range bases {
		if a%n == 0 {
			continue
		}
		x := powMod(a%n, d, n)
		if x == 1 || x == n-1 {
			continue
		}
		ok := false
		for r := 1; r < s; r++ {
			x = mulMod(x, x, n)
			if x == n-1 {
				ok = true
				break
			}
		}
		if !ok {
			return false
		}
	}
	return true
}

func pollardRho(n uint64) uint64 {
	if n%2 == 0 {
		return 2
	}
	if n%3 == 0 {
		return 3
	}
	for {
		y := nextRand()%(n-1) + 1
		c := nextRand()%(n-1) + 1
		m := uint64(128)
		g := uint64(1)
		r := uint64(1)
		q := uint64(1)
		var x, ys uint64
		for g == 1 {
			x = y
			for i := uint64(0); i < r; i++ {
				y = (mulMod(y, y, n) + c) % n
			}
			k := uint64(0)
			for k < r && g == 1 {
				ys = y
				lim := m
				if r-k < lim {
					lim = r - k
				}
				q = 1
				for i := uint64(0); i < lim; i++ {
					y = (mulMod(y, y, n) + c) % n
					var diff uint64
					if x > y {
						diff = x - y
					} else {
						diff = y - x
					}
					if diff == 0 {
						q = 0
					} else {
						q = mulMod(q, diff, n)
					}
				}
				g = gcd64(q, n)
				k += lim
			}
			r <<= 1
		}
		if g == n {
			g = 1
			for g == 1 {
				ys = (mulMod(ys, ys, n) + c) % n
				var diff uint64
				if x > ys {
					diff = x - ys
				} else {
					diff = ys - x
				}
				g = gcd64(diff, n)
			}
		}
		if g != n {
			return g
		}
	}
}

func factor(n uint64, mp map[uint64]int) {
	if n == 1 {
		return
	}
	for _, p := range smallPrimes {
		if n%p == 0 {
			mp[p]++
			factor(n/p, mp)
			return
		}
	}
	if isPrime(n) {
		mp[n]++
		return
	}
	d := pollardRho(n)
	factor(d, mp)
	factor(n/d, mp)
}

func main() {
	fs := NewScanner()
	n := int(fs.NextUint64())
	X := fs.NextUint64()
	Y := fs.NextUint64()

	if Y%X != 0 {
		os.Stdout.WriteString("0")
		return
	}

	M := Y / X
	pm := make(map[uint64]int)
	if M > 1 {
		factor(M, pm)
	}
	primes := make([]uint64, 0, len(pm))
	for p := range pm {
		primes = append(primes, p)
	}

	k := len(primes)
	size := 1 << uint(k)
	freqA := make([]uint64, size)
	freqB := make([]uint64, size)

	for i := 0; i < n; i++ {
		a := fs.NextUint64()

		if a%X == 0 {
			d := a / X
			mask := 0
			for j, p := range primes {
				if d%p == 0 {
					mask |= 1 << uint(j)
				}
			}
			freqA[mask]++
		}

		if Y%a == 0 {
			d := Y / a
			mask := 0
			for j, p := range primes {
				if d%p == 0 {
					mask |= 1 << uint(j)
				}
			}
			freqB[mask]++
		}
	}

	F := make([]uint64, size)
	copy(F, freqA)
	for i := 0; i < k; i++ {
		bit := 1 << uint(i)
		for mask := 0; mask < size; mask++ {
			if mask&bit != 0 {
				F[mask] += F[mask^bit]
			}
		}
	}

	full := size - 1
	var ans uint64
	for mask, cnt := range freqB {
		if cnt > 0 {
			ans += cnt * F[full^mask]
		}
	}

	os.Stdout.WriteString(strconv.FormatUint(ans, 10))
}