Construct Target Array With Multiple Sums

hard heap math reverse simulation

Problem

You begin with an array of n ones. In one move you pick any index, compute the sum of the whole array at that moment, and overwrite the chosen element with that sum. Given a target array of positive integers, decide whether some sequence of moves turns the all-ones array into exactly the target.

The array can hold up to 5·10⁴ elements and each value can be as large as 10⁹, so the sums explode far too fast to simulate forward.

Inputtarget = [9, 3, 5]
Outputtrue
[1,1,1] → [1,3,1] → [1,3,5] → [9,3,5]: each move writes the current sum into one slot.

import heapq

def is_possible(target):
    total = sum(target)
    heap = [-x for x in target]
    heapq.heapify(heap)
    while True:
        largest = -heapq.heappop(heap)
        rest = total - largest
        if largest == 1 or rest == 1:
            return True
        if largest < rest or rest == 0 or largest % rest == 0:
            return False
        prev = largest % rest
        total = rest + prev
        heapq.heappush(heap, -prev)
function isPossible(target) {
  // a sorted array acts as the max-heap here (n is small)
  const heap = [...target].sort((a, b) => b - a);
  let total = target.reduce((s, v) => s + v, 0);
  while (true) {
    const largest = heap.shift();
    const rest = total - largest;
    if (largest === 1 || rest === 1) return true;
    if (largest < rest || rest === 0 || largest % rest === 0) return false;
    const prev = largest % rest;
    total = rest + prev;
    let i = 0;
    while (i < heap.length && heap[i] >= prev) i++;
    heap.splice(i, 0, prev);
  }
}
boolean isPossible(int[] target) {
    PriorityQueue<Long> heap = new PriorityQueue<>(Collections.reverseOrder());
    long total = 0;
    for (int v : target) { total += v; heap.offer((long) v); }
    while (true) {
        long largest = heap.poll();
        long rest = total - largest;
        if (largest == 1 || rest == 1) return true;
        if (largest < rest || rest == 0 || largest % rest == 0) return false;
        long prev = largest % rest;
        total = rest + prev;
        heap.offer(prev);
    }
}
bool isPossible(vector<int>& target) {
    priority_queue<long long> heap;
    long long total = 0;
    for (int v : target) { total += v; heap.push(v); }
    while (true) {
        long long largest = heap.top(); heap.pop();
        long long rest = total - largest;
        if (largest == 1 || rest == 1) return true;
        if (largest < rest || rest == 0 || largest % rest == 0) return false;
        long long prev = largest % rest;
        total = rest + prev;
        heap.push(prev);
    }
}
Time: O(n · log M · log n) Space: O(n)