← Home
```go
package main

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

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

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

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

	// We use a list-like structure. We'll simulate with a slice approach.
	// But n can be up to 150000, and each operation removes one element,
	// so at most 150000 operations. Each operation requires finding the
	// smallest duplicate and the first two occurrences.

	// Use a different approach: maintain the array as a linked list for
	// efficient removal, and use a sorted structure to track duplicates.

	// Linked list approach:
	// - next[i], prev[i] for navigation
	// - For each value, maintain a sorted set of indices
	// - Use a min-heap or sorted set of values that have duplicates

	// Let's use a treemap-like structure.
	// For each value, store a sorted list of positions.
	// Use a sorted set (min-heap) of values that have >= 2 occurrences.

	type node struct {
		val        int64
		prev, next int
		alive      bool
	}

	nodes := make([]node, n)
	for i := 0; i < n; i++ {
		nodes[i] = node{val: a[i], prev: i - 1, next: i + 1, alive: true}
	}

	// Map from value to sorted slice of indices (in list order)
	valIndices := make(map[int64][]int)
	for i := 0; i < n; i++ {
		valIndices[a[i]] = append(valIndices[a[i]], i)
	}

	// Min-heap of values that have duplicates
	// Use a sorted set instead - we need the minimum value with >= 2 occurrences
	// Use a TreeSet-like structure via sorted slice or use a priority queue

	// Let's use a sorted set (balanced BST) - in Go we can use a sorted slice
	// or a heap. Since values can be large, let's use a min-heap of values
	// that have >= 2 entries.

	// Actually, let's use a min-heap. But we need to handle the case where
	// a value is in the heap but no longer has >= 2 occurrences (lazy deletion).

	dupHeap := make([]int64, 0)
	dupSet := make(map[int64]bool)

	for v, indices := range valIndices {
		if len(indices) >= 2 {
			dupHeap = append(dupHeap, v)
			dupSet[v] = true
		}
	}
	sort.Slice(dupHeap, func(i, j int) bool { return dupHeap[i] < dupHeap[j] })

	pushHeap := func(v int64) {
		if !dupSet[v] {
			dupSet[v] = true
			dupHeap = append(dupHeap, v)
			sort.Slice(dupHeap, func(i, j int) bool { return dupHeap[i] < dupHeap[j] })
		}
	}
	_ = pushHeap

	for len(dupHeap) > 0 {
		// Pop minimum
		var x int64
		for len(dupHeap) > 0 {
			x = dupHeap[0]
			indices := valIndices[x]
			if len(indices) >= 2 {
				break
			}
			delete(dupSet, x)
			dupHeap = dupHeap[1:]
		}
		if len(dupHeap) == 0 {
			break
		}

		indices := valIndices[x]
		idx1 := indices[0]
		idx2 := indices[1]

		// Remove idx1 from linked list
		nodes[idx1].alive = false
		p, nx := nodes[idx1].prev, nodes[idx1].next
		if p >= 0 {
			nodes[p].next = nx
		}
		if nx < n {
			nodes[nx].prev = p
		}

		// Update idx2's value to 2*x
		newVal := 2 * x
		nodes[idx2].val = newVal

		// Update valIndices for x: remove first two
		valIndices[x] = indices[2:]
		if len(valIndices[x]) < 2 {
			delete(dupSet, x)
			dupHeap = dupHeap[1:]
		}

		// Add idx2 to newVal's indices (in sorted order by position)
		lst := valIndices[newVal]
		pos := sort.SearchInts(lst, idx2)
		lst = append(lst, 0)
		copy(lst[pos+1:], lst[pos:])
		lst[pos] = idx2
		valIndices[newVal] = lst

		if len(valIndices[newVal]) >= 2 && !dupSet[newVal] {
			dupSet[newVal] = true
			dupHeap = append(dupHeap, newVal)
			sort.Slice(dupHeap, func(i, j int) bool { return dupHeap[i] < dupHeap[j] })
		}
	}

	result := make([]int64, 0)
	for i := 0; i < n; i++ {
		if nodes[i].alive {
			result = append(result, nodes[i].val)
		}
	}
	fmt.Fprintln(writer, len(result))
	for i, v := range result {
		if i > 0 {
			fmt.Fprint(writer, " ")
		}
		fmt.Fprint(writer, v)
	}
	fmt.Fprintln(writer)
}
```