• CF1672I PermutationForces


    link

    首先有个贪心:假设答案已知,则每次可以任取一个。

    令权值 \(c_i = i - p_i\)

    首先证明:删除一个数不会使得另一个能删的数变得不能删 (Lemma I)。设 \(i < j\),则可以通过分 \(p_i < p_j\)(显然),\(p_i > p_j\) (分权值正负讨论)两类证明。

    然后证明删一个数不会使另一个现在还不能删的数 \(|c_i|\) 变大,方法类似,这样就证明了贪心。

    为了避免二分答案,改成每次选 \(|c_i|\) 最小的删掉,并动态维护当前的答案 \(A\)

    根据 (Lemma I)\(|c_i| \le A\) 的权值可以不用维护了,当然也不用显式地删除,如果权值变号了可以不维护绝对值的变化,看作 \(|c_i|\) 是负数。

    绝对值带来了相当大的麻烦,所以我们一开始就把数分成两类:\(i \le p_i\)\(i > p_i\)。注意到维护的数绝对值的符号不会改变(否则中间存在一个时刻 \(c_i = 0\),从而这个数不被继续维护),分别维护。

    \((i, p_i)\) 视为二维平面上的一个点,则删除 \((i, p_i)\) 相当与使得 \(i\) 左上角和右下角的点 \(|c_i|\)\(1\)(删除权值最小的点不会导致其他点权值增大,除非符号改变)。

    维护二维平面并不方便,但我们可以维护一定的单调性:设 \(c_i > 0\),则我们只需要维护所有 \(\boldsymbol {c_i > 0}\) \(p_i\) 的前缀最大值(否则一定不是权值最小),对于 \(c_i \le 0\),维护后缀最小值。

    由于现在有单调性,矩形加变成了区间加,这样可以直接用线段树维护权值最小值。

    用线段树维护区间 min/max 求出前缀最大/后缀最小的变化,每次新加入点时算出 \(c_i\) 即可。复杂度 \(\mathcal O(n \log n)\),常数较大。

    实现

  • 相关阅读:
    codespell
    IDEA打开就闪退或关闭详细解决办法
    git log 空格 翻页
    Vue+ElementUI 分页器elpagination的使用方法
    Vue中computed用法 computed比较适合对多个变量或者对象进行处理后返回一个结果值 计算属性
    word如何删除文本中多余的空行
    Notepad++删除空白行
    Vue生命周期详解
    elementui 自定义树形控件特定行里字体的颜色 content[i].style.color = '#ffff'
    git学习
  • 原文地址:https://www.cnblogs.com/RiverHamster/p/cf1672i.html
Copyright © 2020-2023  润新知