把每个递增二次函数看成有序序列,用堆做 n 路归并取前 m 项。
OJ: luogu
题目 ID: P2085
难度:普及/提高-
标签:多路归并二叉堆python
日期: 2026-07-16 21:00
题意
给出多个在正整数域递增的二次函数,输出所有函数值合并后的前 m 小。
思路
每个函数产生 F(1),F(2),... 一条有序序列。堆中先放每条序列第一项;弹出 (value,function,x) 后,输出它并压入同函数的 x+1,就是标准多路归并。
Python 知识
- 堆元组自动按函数值优先排序,并用后续字段稳定打破平局。
- 局部
value(function, x)集中表达二次式。 print(*answers)直接空格分隔输出。
代码
python
import heapq
import sys
data = iter(map(int, sys.stdin.buffer.read().split()))
n, required = next(data), next(data)
functions = [(next(data), next(data), next(data)) for _ in range(n)]
def value(function, x):
a, b, c = functions[function]
return a * x * x + b * x + c
heap = [(value(i, 1), i, 1) for i in range(n)]
heapq.heapify(heap)
answers = []
for _ in range(required):
result, function, x = heapq.heappop(heap)
answers.append(str(result))
x += 1
heapq.heappush(heap, (value(function, x), function, x))
print(*answers)复杂度
时间
总结
看到许多单调序列的全局前若干小值,应优先想到“每路只保留当前头”的堆归并。