1 条题解

  • 0
    @ 2025-10-19 19:13:19

    题目分析

    这个问题要求我们通过最多 mm 次减一操作,在必须有一个位置变为 00 的条件下,最小化相邻元素差的最大值 zz

    算法思路

    核心思想:二分答案 + 贪心调整

    1. 二分答案:二分查找最小的 zz
    2. 可行性检查:对于每个候选的 zz,检查是否存在一个位置 kk 可以变为 00,且总操作次数不超过 mm

    关键步骤

    1. 二分框架

    int l = 0, r = 1e9 + 7, ans;
    while(l < r){
        int mid = l + r >> 1;
        if(check(mid)){
            r = mid;
            ans = check(mid);
        } else {
            l = mid + 1;
        }
    }
    

    2. 可行性检查 check(p)

    • 步骤1:从左到右调整数组,确保 b[i]b[i1]+pb[i] \leq b[i-1] + p
    • 步骤2:从右到左调整数组,确保 b[i]b[i+1]+pb[i] \leq b[i+1] + p
    • 步骤3:计算总操作次数 w=(a[i]b[i])w = \sum (a[i] - b[i])
    • 步骤4:对于每个位置 ii,检查能否将其设为 00

    3. 寻找最优的 kk

    对于每个候选位置 ii

    • 找到受影响的区间 [l,r][l, r]
    • 计算将该区间调整为以 ii00 的"V"形所需的额外操作数
    • 检查总操作数是否 m\leq m

    时间复杂度

    • 二分O(logMAX)O(\log \text{MAX}),其中 MAX 是值域
    • 可行性检查O(n)O(n)
    • 总复杂度O(nlogMAX)O(n \log \text{MAX})

    代码亮点

    1. 双向调整:先从左到右,再从右到左,确保相邻差 z\leq z
    2. V形计算:利用等差数列公式快速计算以某个位置为谷底的操作次数
    3. 滑动窗口:使用双指针 l,rl, r 快速确定受影响区间
    4. 前缀和优化s[i]s[i] 数组加速区间和计算

    样例解析

    对于样例:

    16 15
    8 7 6 5 5 5 5 5 6 6 7 8 9 7 5 5
    

    z=2z=2 时,选择 k=1k=1(第一个位置为0)可以在15次操作内满足条件。

    这个解法充分利用了二分答案的框架,结合贪心调整和数学计算,在 nn 达到 10610^6 时仍能高效运行。

    • 1

    信息

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