#19288. 金榜题名
金榜题名
你好!我是你的OI金牌教练。
这一期我们将穿越回大唐盛世,聚焦于中国历史上最重要的人才选拔制度——科举制,特别是武则天时期开创的殿试制度。
我们将通过这道题目,学习一种非常实用的数据结构——优先队列 (Priority Queue) / 堆 (Heap)。这道题目符合 GESP 6级 难度,考察如何在动态数据流中高效地维护“前 大”的元素。
第一部分:背景知识讲解
1. 科举制与殿试 (The Imperial Examination & Palace Exam)
科举制起源于隋朝,完善于唐朝。它打破了世族门阀对官场的垄断,允许平民通过考试成为官员。
- 殿试的诞生:唐朝时期,武则天为了广揽人才,打击旧贵族势力,亲自在洛阳宫殿策问贡士,这标志着殿试制度的诞生。殿试是最高级别的考试,由皇帝亲自主持,考中的人被称为“天子门生”。
2. 榜单的动态变化
在阅卷过程中,考官们会陆续批阅出考生的分数。皇帝只关心目前分数最高的 个人(即“金榜题名”的候选人)。 每当有一份新的高分试卷出现,它可能会挤掉原本在前 名中分数最低的那个人,从而改变“金榜”的入围名单。
3. 算法模型:Top-K 问题
如果每来一个分数我们都重新排序,时间复杂度是 或 ,当操作频繁时效率太低。 我们需要一种数据结构,能够:
- 快速插入新元素。
- 快速找出(并删除)当前集合中的最小值(因为我们要淘汰前 名里最差的那个,给更好的人腾位置)。
这就是小根堆 (Min-Heap) 的应用场景。虽然我们要维护的是“前 大”,但为了方便淘汰,我们需要用小根堆来维护这 个数,堆顶就是这 个数里的“守门员”。
第二部分:题目内容
题目名称:金榜题名 (The Gold List)
题目描述
武则天在神都洛阳主持殿试。共有 次事件发生,事件分为两种类型:
- 阅卷 (Type 1):考官批阅了一份新试卷,得分为 。如果目前暂定的“金榜”名单未满 人,该考生直接进入名单;如果已满 人,且该考生成绩严格高于名单中分数最低的人,则该考生进入名单,替换掉分数最低的那位。否则,该考生落榜。
- 询问 (Type 2):武则天询问当前“金榜”名单中所有考生的分数总和。
请你编写程序,模拟这个过程,并回答每一次询问。
输入格式
第一行包含两个正整数 。
- 表示事件的总数。
- 表示金榜名单的最大名额。
接下来 行,每行描述一个事件:
1 S:表示阅卷事件,考生分数为 ( 为正整数)。2:表示询问事件,输出当前金榜上所有人的分数之和。
输出格式
对于每个类型为 2 的事件,输出一行一个整数,表示当前金榜的分数总和。
如果当前金榜为空(还没人分数入账),输出 0。
输入输出样例 #1
输入:
6 3
1 10
1 20
2
1 5
1 30
2
输出:
30
60
样例 #1 解释: 名额 。
1 10:金榜{10},和=10。1 20:金榜{10, 20},和=30。2:输出 30。1 5:当前金榜未满(2人),直接进。金榜{5, 10, 20},和=35。1 30:当前金榜已满(3人)。最低分是 5。,30 替换 5。金榜{10, 20, 30},和=60。2:输出 60。
输入输出样例 #2
输入:
7 2
1 100
1 100
1 50
2
1 200
1 150
2
输出:
200
350
样例 #2 解释: 名额 。
1 100:{100}。1 100:{100, 100}。1 50:满员。最低分 100。 不大于 100,落榜。金榜不变{100, 100}。2:输出 200。1 200:,替换一个。金榜{100, 200}。1 150:,替换最低的 100。金榜{150, 200}。2:输出 350。
数据范围
对于 的数据:
- 保证至少有一次询问。