1 条题解

  • 0
    @ 2026-5-6 15:06:56

    C. 更新查询 – 详细题解

    问题重述

    给定初始字符串 ss(长度 nn),一个索引数组 ind\text{ind}(长度 mm)和一个字符数组 cc(长度 mm)。每次操作选择 ind\text{ind} 中的一个位置 ppcc 中的一个字符 chch,将 sps_p 更新为 chch。所有操作按某种顺序依次执行。我们可以任意重排 ind\text{ind}cc 的顺序(即重新排列操作顺序和分配字符)。求经过 mm 次操作后能得到的最小字典序的 ss

    核心观察

    • 一个位置可能被多次更新。最终该位置的值由最后一次(即该位置上的最后一次操作)的字符决定。之前的更新会被覆盖,因此不影响结果。
    • 对于每个位置 ii1in1 \le i \le n),记 fif_iind\text{ind}ii 出现的次数。若 fi=0f_i = 0,则该位置永远不会被修改,最终字符就是 sis_i 本身。
    • fi>0f_i > 0,则我们将会对该位置执行 fif_i 次操作,其中最后一次操作决定最终字符。前 fi1f_i-1 次操作可以任意使用 cc 中的字符(它们会被覆盖,不影响结果),但会消耗掉 cc 中的某些字母。
    • 目标:使最终的字符串 ss 字典序最小。字典序的比较是从左到右逐字符进行的,因此我们应优先让靠前的位置尽可能小。

    贪心策略

    从左到右依次处理每个位置 ii

    • 如果 fi=0f_i = 0,则 sis_i 不变。
    • 如果 fi>0f_i > 0
      • 我们需要为这个位置选择一个最终字符。为了字典序最小,我们应从 cc 中剩余的所有字母里选择最小的那个作为该位置的最终值。
      • 选择后,将该字母从 cc 的计数中移除(表示已用于最后一次操作)。
      • 该位置还需要 fi1f_i - 1 个额外的操作(它们会被覆盖)。这些操作可以使用 cc任意剩余的字母,因为无论用什么都对最终结果没有影响。为了不浪费小字母(后面可能还需要),我们应该用最大的字母来填充这些额外的操作。具体做法是:从 zz 向下遍历,尽可能多地取大字母,直到凑够 fi1f_i - 1 个。
    • 处理完所有位置后,cc 中可能还有剩余字母,但所有操作已经用完?注意 mm 等于所有 fif_i 之和,因此 cc 中的字母总数正好等于 fi\sum f_i,所以最后计数会归零。

    正确性说明

    • 字典序最小:由于我们是从左到右处理,每个位置都使用了当前可用的最小字母作为最终值,保证了前面位置尽可能小。同时,我们用大字母填充多余的操作,保留了小字母给后面的位置,从而不会破坏后续的字典序优势。
    • 可行性:因为总操作数等于 cc 中字母总数,且每个位置 fi>0f_i>0 时我们分配了 11 个最终字母和 fi1f_i-1 个填充字母,总共 fif_i 个。整个过程消耗完所有字母,因此是可行的。

    算法步骤

    1. 统计 ind\text{ind} 中每个位置的出现次数 fif_i1in1 \le i \le n)。
    2. 统计 cc 中每个字母的频率 cnt[0..25]\text{cnt}[0..25]
    3. 新建一个空字符串 ans\text{ans}
    4. 对于 i=1i = 1nn
      • 如果 fi=0f_i = 0:将 sis_i 追加到 ans\text{ans}
      • 否则:
        • 找到最小的字母 chch(从 'a''z')使得 cnt[ch]>0\text{cnt}[ch] > 0,将 chch 追加到 ans\text{ans},并将 cnt[ch]\text{cnt}[ch]11
        • 还需要 fi1f_i - 1 个字母来填充。从 zz 向下到 aa,每次尽量取最多,直到取够 fi1f_i - 1 个。(实际上,我们不需要显式记录这些填充操作,只需将 cnt\text{cnt} 中的对应字母减少即可,因为填充字母不参与最终结果。)
    5. 输出 ans\text{ans}

    复杂度

    • 统计频率:O(n+m)O(n + m)
    • 处理每个位置:对于每个 fi>0f_i > 0 的位置,寻找最小字母需要 O(26)O(26),填充大字母也需要 O(26)O(26)。由于 nnmm 的总和不超过 2×1052\times 10^5,总复杂度 O((n+m)26)O((n+m)\cdot 26),完全可以接受。

    示例验证

    以样例2为例:s="meow"s=\text{"meow"}n=4n=4ind=[1,2,1,4]\text{ind}=[1,2,1,4]c="zcwz"c=\text{"zcwz"}
    统计 ff:位置1出现2次,位置2出现1次,位置3出现0次,位置4出现1次。
    cc 字母频率:z:2, c:1, w:1。
    从左到右:

    • i=1i=1 (f=2f=2):取最小字母 c → ans="c",cnt[c]=0。还需1个填充,取最大字母 z,cnt[z]=1。
    • i=2i=2 (f=1f=1):取最小字母 w → ans="cw",cnt[w]=0。
    • i=3i=3 (f=0f=0):原字符 o → ans="cwo"。
    • i=4i=4 (f=1f=1):取最小字母 z → ans="cw o z" = "cwoz"。结果与输出一致。

    总结

    本题的核心是理解“最后一次操作决定最终值”以及“多余的更新可以用任意字符填充”。通过贪心地为每个被更新的位置分配当前最小的字母作为最终值,并用最大的字母填充多余操作,即可得到字典序最小的结果。

    • 1

    信息

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