1 条题解

  • 0
    @ 2026-4-2 21:54:06

    题目回顾

    给定数组 a1,a2,,ana_1, a_2, \dots, a_n,元素均为正整数。
    可以选一些位置染红,要求不能有相邻红位置
    得分定义为:

    $$\text{score} = \max(\text{红色元素}) + \min(\text{红色元素}) + \text{红色元素个数} $$

    求最大可能得分。


    第一步:最优解必然包含全局最大值

    设全局最大值为 M=max(a)M = \max(a)
    假设某个最优解中,红色元素的最大值 m<Mm < M
    那么我们可以加入任意一个值为 MM 的位置(如果相邻位置有红,则删掉那个红,最多删 22 个)。
    这样变化后:

    • 最大值从 mm 变成 MM,增加了 Mm1M - m \ge 1
    • 元素个数最多减少 22
    • 最小值不变或可能变大(如果删掉的是最小值,最小值可能变大,但不会让分数变小)。

    所以新分数 \ge 旧分数 +(Mm)2+ (M - m) - 2
    Mm2M - m \ge 2 时,新分数严格更大;当 Mm=1M - m = 1 时,新分数至少不变。
    因此最优解中一定存在某个红色元素等于 MM


    第二步:枚举最小值 ll,维护可选区间

    r=Mr = M 固定。
    我们考虑所有 ai[l,r]a_i \in [l, r] 的位置。
    这些位置被允许选,并且它们必须包含至少一个 ai=ra_i = r

    问题转化为:

    在数组的某些位置(ai[l,r]a_i \in [l, r])中选一个子集,不能相邻,必须包含至少一个 rr,最大化:

    r+l+所选个数r + l + \text{所选个数}

    因为 rr 固定,我们要最大化 l+所选个数l + \text{所选个数}


    第三步:对每个 ll,如何计算最大可选个数?

    允许的位置把数组分成若干连续段(connected components)。
    在一个长度为 ss 的连续段中,不能相邻选,最多选 s/2\lceil s/2 \rceil 个。

    那么如果不考虑必须选 rr,总个数为:

    $$\text{total}(l) = \sum_{\text{每个段}} \lceil \text{段长} / 2 \rceil $$

    第四步:保证至少选一个 rr

    如果某个段里包含 rr,那么选 s/2\lceil s/2 \rceil 个时,可能包含 rr,也可能不包含。
    能不能保证包含 rr

    关键观察:

    • 在一个段里,如果固定选 s/2\lceil s/2 \rceil 个,有两种“极值”选法:
      从第一个位置开始选(奇偶性 1),或者从第二个位置开始选(奇偶性 2)。
    • 一个段里的某个具体位置 pp(从段头数第 kk 个)能被包含在“最多选”方案中,当且仅当:
      要么选奇数位置,要么选偶数位置,并且 pp 属于被选的那一组。

    因此:

    • 如果 rr 在某个段里,并且它可以在奇数位置被选到(即段头到它的距离是偶数,从 00 开始计),则这个段可以通过选择奇数位置来包含 rr
    • 同样,如果 rr偶数位置被选到(距离是奇数),则选偶数位置即可包含 rr

    所以对于包含 rr 的段,有两种选法(奇/偶)。
    我们要看:是否存在一个段,使得它的两种选法之一同时满足:

    1. 该段选了 s/2\lceil s/2 \rceil 个元素(最大个数)。
    2. 包含 rr

    第五步:维护两个布尔值

    对每个段,维护:

    • can_odd:是否可以通过选奇数位置(从段头 1 开始)包含 rr
    • can_even:是否可以通过选偶数位置包含 rr

    如果某个段里,rr 出现在奇数位置(段内索引从 1 开始),那么 can_odd = true
    如果出现在偶数位置,那么 can_even = true
    (注意:如果段里 rr 出现多次,可能两个都 true。)


    第六步:全局判断能否包含 rr

    若所有段中,奇数选法都不包含 rr,且偶数选法也都不包含 rr,则必须放弃一个段的一个元素来换 rr,总个数减 1。

    否则,我们可以选择一种选法(奇或偶),使得每个段都取 s/2\lceil s/2 \rceil,且至少一个段包含了 rr


    第七步:枚举 ll 的过程

    我们从大到小枚举 ll(从 rr 往下到最小值),同时维护 DSU(并查集)来合并相邻的“可选”段。

    ll 减小时,新加入一些位置 ai=la_i = l,这些位置可能:

    • 单独成一个段,
    • 或连接左右两个段(如果它们已经是可选状态)。

    每次合并时更新:

    • 段长
    • can_oddcan_even(根据 rr 在当前段内的位置合并)

    然后计算:

    $$\text{score}(l) = r + l + \text{total}(l) - \delta $$

    其中 δ=1\delta = 1 如果“无法在保持最大个数下包含 rr”,否则 δ=0\delta = 0


    第八步:复杂度

    每个位置被加入一次,合并用 DSU 并查集,总复杂度 O(nα(n))O(n \alpha(n))


    最终算法步骤

    1. 找到全局最大值 r=max(a)r = \max(a)
    2. 按值从大到小枚举 ll(去重)。
    3. 维护一个布尔数组 active,标记 aila_i \ge l
    4. ll 减小,新激活的位置尝试与左右合并(DSU)。
    5. 每个 DSU 节点维护:
      • 段长
      • has_r_odd:段内是否存在 rr 在奇数位置(从段头 1 开始数)
      • has_r_even:段内是否存在 rr 在偶数位置
    6. 全局维护:
      • total_odd:所有段的奇数选法的总数(即 s/2\sum \lceil s/2 \rceil
      • total_even:所有段的偶数选法的总数(其实等于 total_odd,因为 s/2\lceil s/2 \rceil 与奇偶无关,但区别在于包含 rr 的可能性)
    7. 全局检查:是否存在一个段,其 has_r_odd = true,或者 has_r_even = true
      若没有,则答案 =r+l+total1= r + l + \text{total} - 1
      否则 =r+l+total= r + l + \text{total}
    8. 取所有 ll 的最大值。

    示例验证(第三组数据)

    数组:[3,3,3,3,4,1,2,3,5,4][3,3,3,3,4,1,2,3,5,4]r=5r=5

    • l=5l=5:只有 55 一个元素,段长 1,可选 1 个,包含 rr,得分 =5+5+1=11=5+5+1=11
    • l=4l=4:可选 4,5,44,5,4,位置 5 的 4 和位置 10 的 4 与位置 9 的 5 形成两个段? 不对,检查:
      激活位置:5(4), 9(5), 10(4) → 实际上位置 5 与位置 9 不相邻,所以段是 [5] 和 [9,10]。
      段1: [5] 长1 → 可选1,rr 不在。
      段2: [9,10] 长2 → 可选1(奇数选法取9,偶数取10),rr 在 9(奇数位),所以 has_r_odd=true
      总数=1+1=2,可以包含 rr,得分=5+4+2=11。
    • l=3l=3:激活很多,计算得最大 12。

    最终答案 12,匹配样例。


    总结

    本题核心:

    1. 固定最大值 rr 必选。
    2. 枚举最小值 ll,用 DSU 维护可选段。
    3. 每个段最多选 s/2\lceil s/2 \rceil 个,奇偶两种选法。
    4. 检查是否能包含 rr,不能则总个数减 1。
    5. max(r+l+count)\max(r + l + \text{count})

    复杂度 O(nlogn)O(n \log n)O(nα(n))O(n \alpha(n)),可以过 2×1052\times 10^5

    • 1

    信息

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