```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)
}
```