zoukankan      html  css  js  c++  java
  • 带权二分-一丢丢感悟

    问题:边界条件的考虑方式,权值相等时,第二关键字应该是最大化还是最小化。

    用 hzwer 的选 (k) 个白点那道题来说吧,给每个白点增加 (mid) 的权值,计算 MST 的白点数量 (cnt)

    (mid) 增大, (cnt) 减小,二分大概长这样:

        while (l <= r) {
            cnt = check(mid);
            if (cnt <= k) {
                // update ans
                r = mid - 1;
            } else {
                l = mid + 1;
            }
        }
    

    类似一个单调不升的序列,二分一个值,最后肯定是停在一段连续相同的值的左边(因为 (cnt = k) 的时候还在减小 (mid) )。

    如此能保证的只有 (mid - 1) 位置的 (cnt > k) ,它是非法的。

    这种非法情况,应该无论如何都非法。就是说 (mid - 1) 位置对应的各种 (cnt_{min}, cdots, cnt_{max}) ,都大于 (k) (否则合法的情况就可能在 (mid - 1) 位置,这时候该选 (mid) 还是 (mid - 1) 就说不清了),所以应该保证 (cnt_{min}>k) 才正确。

    说完了。

    具体放到题里面,求 (cnt) 时,点权相同时,最小化 (cnt) 。反过来说有人二分里面更新答案时用的是 cnt >= k , 那就应该优先选白点,计算 (cnt_{max})

    似乎大佬们有不同的解释,不过暂时我只能这样理解,似乎没什么问题。八省联考 2018 林克卡特树 也是这个方式考虑第二关键字。

    update (2019.03.27) : 更简单的理解方法是,原函数加一个一次函数等价与导数加一个常数,也就是向上平移。每次求得的是导数与 (x) 轴交点。导数有时平行于 (x) 轴就需要上面说的方法解决了。

  • 相关阅读:
    JavaScript事件阶段
    JavaScript阻止事件冒泡
    JavaScript事件冒泡
    JavaScript简单的随机点名系统
    理解Android线程创建流程
    SurfaceFlinger启动篇
    Android系统启动-zygote篇
    Android系统启动-Init篇
    Android系统启动-SystemServer下篇
    Android系统启动-SystemServer上篇
  • 原文地址:https://www.cnblogs.com/ghcred/p/10420387.html
Copyright © 2011-2022 走看看