[AtCoder] ABC471 D — Chargers: subtract the common term
Published on August 16, 2026
Problem: ABC471 D — Chargers
Batteries plug in at time \(t\) with charge \(w\), gain 1 charge per unit time, cap at \(V\). Each query either plugs one in or unplugs the one with the highest charge. A heap keyed on \(w\) is wrong — charges keep moving, so the order looks dynamic.
Writing it out kills the problem. At time \(T\), an unsaturated battery holds
\[\text{charge}(T) = w + (T - t) = T + (w - t)\]\(T\) is the same for everyone, so comparing two batteries is comparing \(w_1 - t_1\) against \(w_2 - t_2\) — constants. The order is fixed at insertion time. Key the heap on \(w - t\), clamp with min(V, ...) on the way out; saturation is safe because the largest \(w - t\) saturates first and ties at \(V\) don’t matter.
import sys
from heapq import heappush, heappop
def main():
data = sys.stdin.buffer.read().split()
q, v = int(data[0]), int(data[1])
out, pq, i = [], [], 2
for _ in range(q):
if data[i] == b'1':
t, w = int(data[i + 1]), int(data[i + 2])
heappush(pq, (-(w - t), t, w))
i += 3
else:
cur = int(data[i + 1])
if pq:
_, t, w = heappop(pq)
out.append(str(min(v, w + cur - t)))
else:
out.append('-1')
i += 2
sys.stdout.write('\n'.join(out))
main()
\(O(Q \log Q)\). I got here on gut feeling, but the gut was just pattern-matching the actual reason: whenever every candidate’s value is common_part + item_specific_part, the common part drops out of every comparison and what’s left is a static key.
Tags: competitive_programming, atcoder, heap, invariants