1 条题解

  • 0
    @ 2026-4-15 22:07:59

    G. 厨师与粥 详细题解

    题目核心理解

    nn 个学生在队列中等待厨师分粥,厨师会持续分粥 DD 分钟。 每分钟开始时,厨师给当前队首学生一份粥; 学生在第 xx 分钟开始领到粥后,会在第 x+six+s_i 分钟结束时返回队列。

    学生返回规则:

    1. 按优先级 kik_i 插队,排在最后一个优先级不低于自己的学生之后;
    2. 同一时间返回的学生,按 sis_i 升序排列。

    目标:求出所有学生都至少领到一次粥的最早时间。 若 DD 分钟内无法全员领到,输出 1-1


    核心思路

    1. 队列拆分

    • 初始队列 Q1Q_1:用数组保存,指针 PP 指向当前队首,代表还没领过第一次粥的学生。
    • 回归队列 Q2Q_2:用优先队列维护,按优先级降序、sis_i 升序排序。

    2. 关键优化:后缀最大值

    预处理后缀最大值数组 sufMaxsufMaxsufMax[P]sufMax[P] 表示初始队列从 PP 到末尾的最大优先级

    选择规则:

    • Q2Q_2 队首优先级 sufMax[P]sufMax[P]:优先服务初始队列 Q1Q_1
    • 否则:优先服务回归队列 Q2Q_2

    3. 回归事件处理

    用数组 eateat 记录回归事件: eat[t]eat[t] 存储在第 tt 分钟结束时返回的所有学生。 每分钟结束后,将这批学生加入优先队列。


    算法流程

    1. 读入 n,Dn,D 以及每个学生的 ki,sik_i,s_i
    2. 预处理后缀最大值数组 sufMaxsufMax
    3. 初始化指针 P=1P=1、答案 ans=1ans=-1、访问标记数组 visvis
    4. 逐分钟模拟(从 11DD):
      • 根据后缀最大值判断,选择 Q1Q_1Q2Q_2 的学生领粥。
      • 如果该学生是第一次领粥,打上标记。
      • 计算其回归时间,若不超过 DD 则加入对应 eateat 数组。
      • 处理当前分钟结束后回归的学生,加入优先队列。
      • P=n+1P = n+1(全员领过),记录当前时间并提前结束。
    5. 输出答案。

    公式与复杂度分析

    时间复杂度:

    O(Dlogn)O(D\log n)

    复杂度说明

    • 逐分钟遍历时间:O(D)O(D)
    • 优先队列单次插入/弹出:O(logn)O(\log n)
    • 总体复杂度可通过 D3×105D\le 3\times10^5n2×105n\le 2\times10^5 的限制。

    空间复杂度:O(n+D)O(n+D),用于存储学生信息、后缀数组、回归事件。

    • 1

    信息

    ID
    6540
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者