← Home
```go
package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	if !scanner.Scan() {
		return
	}
	n, _ := strconv.Atoi(scanner.Text())

	a := make([]int, n)
	minA := 2000000000
	for i := 0; i < n; i++ {
		scanner.Scan()
		val, _ := strconv.Atoi(scanner.Text())
		a[i] = val
		if val < minA {
			minA = val
		}
	}

	check := func(y int) int64 {
		var sum int64
		for _, v := range a {
			// To have sets of size y or y-1, we calculate k = ceil(v / y)
			k := (v + y - 1) / y
			// We must be able to fill k sets with at least y-1 items each
			// So k * (y - 1) <= v
			if int64(k)*int64(y-1) > int64(v) {
				return -1
			}
			sum += int64(k)
		}
		return sum
	}

	// We want to maximize y to minimize the total number of sets.
	// We iterate candidates for y derived from the smallest a_i (minA).
	// Candidates are roughly minA/k.
	// We split the search into two phases based on sqrt(minA).

	limit := int(math.Sqrt(float64(minA)))
	if limit < 2 {
		limit = 2
	}

	// Phase 1: iterate k (number of sets for minA) to find large y candidates
	for k := 1; ; k++ {
		R := minA/k + 1
		if R < limit {
			break
		}
		L := (minA + k - 1) / k

		start := R
		end := L
		if end < limit {
			end = limit
		}

		for y := start; y >= end; y-- {
			if res := check(y); res != -1 {
				fmt.Println(res)
				return
			}
		}
	}

	// Phase 2: linear scan for small y
	for y := limit - 1; y >= 1; y-- {
		if res := check(y); res != -1 {
			fmt.Println(res)
			return
		}
	}
}
```