← Home
```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var n, x, y int
	fmt.Fscan(reader, &n, &x, &y)

	a := make([]int, n)
	maxVal := 0
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &a[i])
		if a[i] > maxVal {
			maxVal = a[i]
		}
	}

	// Count frequency of each number
	maxA := maxVal + 1
	freq := make([]int, maxA+1)
	for _, v := range a {
		freq[v]++
	}

	// Prefix sum of frequencies
	prefix := make([]int, maxA+2)
	for i := 1; i <= maxA; i++ {
		prefix[i] = prefix[i-1] + freq[i]
	}

	// For each prime p, we want all numbers to be multiples of p
	// For a number in range [k*p, (k+1)*p - 1]:
	// - numbers in [k*p, (k+1)*p - 1] can be increased to (k+1)*p
	// - but if cost to increase > cost to delete, we delete
	// Actually we need to consider each multiple interval

	// For a given prime p, consider intervals [k*p, (k+1)*p - 1]
	// Numbers in this interval either:
	// 1. Get deleted: cost x per number
	// 2. Get increased to (k+1)*p: cost (k+1)*p - v for each number v, which is y * ((k+1)*p - v)
	// We want minimum cost for each number independently

	// For each prime p:
	// cost = sum over all intervals [k*p, (k+1)*p-1] of min_cost
	// For numbers in [k*p, (k+1)*p-1]:
	//   delete cost for number v: x
	//   increase cost for number v: y * ((k+1)*p - v)
	//   We pick min(x, y*((k+1)*p - v)) for each v

	// To efficiently compute this, we use prefix sums
	// prefix_count[i] = number of elements <= i
	// prefix_val[i] = sum of elements <= i

	prefixVal := make([]int64, maxA+2)
	for i := 1; i <= maxA; i++ {
		prefixVal[i] = prefixVal[i-1] + int64(freq[i])*int64(i)
	}

	countInRange := func(l, r int) int {
		if l > r {
			return 0
		}
		if r > maxA {
			r = maxA
		}
		if l < 1 {
			l = 1
		}
		if l > r {
			return 0
		}
		return prefix[r] - prefix[l-1]
	}

	sumInRange := func(l, r int) int64 {
		if l > r {
			return 0
		}
		if r > maxA {
			r = maxA
		}
		if l < 1 {
			l = 1
		}
		if l > r {
			return 0
		}
		return prefixVal[r] - prefixVal[l-1]
	}

	const INF = int64(1e18)
	ans := INF

	// Try each prime p
	primes := []int{}
	sieve := make([]bool, 1000001)
	for i := 2; i <= 1000000; i++ {
		if !sieve[i] {
			primes = append(primes, i)
			for j := i * 2; j <= 1000000; j += i {
				sieve[j] = true
			}
		}
	}

	for _, p := range primes {
		cost := int64(0)
		// Intervals: [p, 2p-1], [2p, 3p-1], ...
		for k := 1; k*p <= maxA+p; k++ {
			lo := k * p
			hi := (k+1)*p - 1
			// Numbers in [lo, hi] need to reach (k+1)*p
			// But numbers exactly at lo*p are already multiples, cost 0
			// Actually lo = k*p is a multiple of p, cost 0 to keep
			// Numbers in [lo+1, hi] need to be increased or deleted
			// Numbers at lo: cost 0

			// For numbers in [lo, hi]:
			// At lo: cost 0 (already multiple of p)
			// At lo+1..hi: increase to (k+1)*p costs y*(target - v) or delete costs x

			// For number v in [lo+1, hi]:
			// increase cost: y*((k+1)*p - v)
			// delete cost: x
			// choose min

			// threshold: y*((k+1)*p - v) <= x => (k+1)*p - v <= x/y => v >= (k+1)*p - x/y
			// So if v >= (k+1)*p - x/y, increase; else delete

			target := int64((k + 1) * p)
			// Find split point: v >= target - x/y means increase is cheaper
			// splitV = target - floor(x/y) if y divides x, else target - floor(x/y)
			// increase cost <= delete cost when y*(target-v) <= x => target-v <= x/y => v >= target - x/y
			splitV := int64(target) - int64(x)/int64(y)
			// if y*(target-v) == x, either is fine
			// v >= splitV: increase (if y*(target-v) <= x)
			// actually need y*(target-v) <= x => v >= target - x/y

			// Numbers in [lo, lo] have cost 0 already counted
			// Numbers in [lo+1, hi]:
			l2 := lo + 1
			r2 := hi
			if r2 > maxA {
				r2 = maxA
			}
			if l2 > r2 {
				continue
			}

			// Delete range: [l2, min(r2, splitV-1)]
			delR := int(splitV) - 1
			if delR >= l2 {
				cnt := countInRange(l2, min2(r2, delR))
				cost += int64(cnt) * int64(x)
			}

			// Increase range: [max(l2, splitV), r2]
			incL := int(splitV)
			if incL < l2 {
				incL = l2
			}
			if incL <= r2 {
				cnt := countInRange(incL, r2)
				s := sumInRange(incL, r2)
				cost += target*int64(cnt) - s
				cost *= int64(y)
				cost /= int64(y) // undo
				// Actually: increase cost = y * (target*cnt - sum)
				cost -= target*int64(cnt) - s // undo above
				cost += int64(y) * (target*int64(cnt) - s)
			}
		}
		if cost < ans {
			ans = cost
		}
	}

	fmt.Fprintln(writer, ans)
}

func min2(a, b int) int {
	if a < b {
		return a
	}
	return b
}
```