#19288. 金榜题名

金榜题名

你好!我是你的OI金牌教练。

这一期我们将穿越回大唐盛世,聚焦于中国历史上最重要的人才选拔制度——科举制,特别是武则天时期开创的殿试制度。

我们将通过这道题目,学习一种非常实用的数据结构——优先队列 (Priority Queue) / 堆 (Heap)。这道题目符合 GESP 6级 难度,考察如何在动态数据流中高效地维护“前 KK 大”的元素。


第一部分:背景知识讲解

1. 科举制与殿试 (The Imperial Examination & Palace Exam)

科举制起源于隋朝,完善于唐朝。它打破了世族门阀对官场的垄断,允许平民通过考试成为官员。

  • 殿试的诞生:唐朝时期,武则天为了广揽人才,打击旧贵族势力,亲自在洛阳宫殿策问贡士,这标志着殿试制度的诞生。殿试是最高级别的考试,由皇帝亲自主持,考中的人被称为“天子门生”。

2. 榜单的动态变化

在阅卷过程中,考官们会陆续批阅出考生的分数。皇帝只关心目前分数最高的 KK 个人(即“金榜题名”的候选人)。 每当有一份新的高分试卷出现,它可能会挤掉原本在前 KK 名中分数最低的那个人,从而改变“金榜”的入围名单。

3. 算法模型:Top-K 问题

如果每来一个分数我们都重新排序,时间复杂度是 O(NlogN)O(N \log N)O(N)O(N),当操作频繁时效率太低。 我们需要一种数据结构,能够:

  1. 快速插入新元素。
  2. 快速找出(并删除)当前集合中的最小值(因为我们要淘汰前 KK 名里最差的那个,给更好的人腾位置)。

这就是小根堆 (Min-Heap) 的应用场景。虽然我们要维护的是“前 KK 大”,但为了方便淘汰,我们需要用小根堆来维护这 KK 个数,堆顶就是这 KK 个数里的“守门员”。


第二部分:题目内容

题目名称:金榜题名 (The Gold List)

题目描述

武则天在神都洛阳主持殿试。共有 NN 次事件发生,事件分为两种类型:

  1. 阅卷 (Type 1):考官批阅了一份新试卷,得分为 SS。如果目前暂定的“金榜”名单未满 KK 人,该考生直接进入名单;如果已满 KK 人,且该考生成绩严格高于名单中分数最低的人,则该考生进入名单,替换掉分数最低的那位。否则,该考生落榜。
  2. 询问 (Type 2):武则天询问当前“金榜”名单中所有考生的分数总和

请你编写程序,模拟这个过程,并回答每一次询问。

输入格式

第一行包含两个正整数 N,KN, K

  • NN 表示事件的总数。
  • KK 表示金榜名单的最大名额。

接下来 NN 行,每行描述一个事件:

  • 1 S:表示阅卷事件,考生分数为 SSSS 为正整数)。
  • 2:表示询问事件,输出当前金榜上所有人的分数之和。

输出格式

对于每个类型为 2 的事件,输出一行一个整数,表示当前金榜的分数总和。 如果当前金榜为空(还没人分数入账),输出 0。

输入输出样例 #1

输入:

6 3
1 10
1 20
2
1 5
1 30
2

输出:

30
60

样例 #1 解释: 名额 K=3K=3

  1. 1 10:金榜 {10},和=10。
  2. 1 20:金榜 {10, 20},和=30。
  3. 2输出 30
  4. 1 5:当前金榜未满(2人),直接进。金榜 {5, 10, 20},和=35。
  5. 1 30:当前金榜已满(3人)。最低分是 5。30>530 > 5,30 替换 5。金榜 {10, 20, 30},和=60。
  6. 2输出 60

输入输出样例 #2

输入:

7 2
1 100
1 100
1 50
2
1 200
1 150
2

输出:

200
350

样例 #2 解释: 名额 K=2K=2

  1. 1 100{100}
  2. 1 100{100, 100}
  3. 1 50:满员。最低分 100。5050 不大于 100,落榜。金榜不变 {100, 100}
  4. 2:输出 200。
  5. 1 200200>100200 > 100,替换一个。金榜 {100, 200}
  6. 1 150150>100150 > 100,替换最低的 100。金榜 {150, 200}
  7. 2:输出 350。

数据范围

对于 100%100\% 的数据:

  • 1N2×1051 \le N \le 2 \times 10^5
  • 1KN1 \le K \le N
  • 1S1091 \le S \le 10^9
  • 保证至少有一次询问。