1 条题解

  • 0
    @ 2025-8-24 23:16:23

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar luanyanjia
    菜 -我ら是个と大に傻む逼なり-

    搬运于2025-08-24 23:16:23,当前版本为作者最后更新于2025-07-22 15:32:23,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    介绍一种比较糖的维护方式。

    首先区间可以从左到右贪心匹配,保证前缀和 0\ge 0 即可。最终折线有一个最大值 mxmx,和最终值 nownow。那么我们删去最后的 mxnowmx - now1-1 即可。化一下式子,答案就是 2c1mx2c_1 - mx,其中 c1c_1 是区间中 11 的数量。

    现在就是要维护区间匹配过程中的 mxmx 即可。即画一条从原点开始的折线,如果碰到 xx 轴就不减了,整个过程的最大值。下面是我在模拟赛时想到的做法:

    建线段树,每个线段树上维护节点代表区间的 mxmx,左右边到最低点的距离 L,RL,R,还有不考虑和 00max\max 时,折线的最大值 mx2mx2

    合并左右儿子的时候,L,R,mx2L,R,mx2 均可以直接计算。对于 mxmx,有 mx=max(mxls,mxrs,Rls+mx2rs)mx = \max(mx_{ls},mx_{rs},R_{ls} + mx2_{rs})

    对于右儿子的过程,第一次碰到 xx 轴前,mx2mx2 是正确的,后面 mxmx 是正确的,其他时候答案一定更小。所以信息就维护对了。

    inline void PushUp(node &i,node ls,node rs){
      i.c1=ls.c1+rs.c1;
      i.R=ls.R+std::max(0,rs.R-ls.L);
      i.L=rs.L+std::max(0,ls.L-rs.R);
      i.mx1=std::max({ls.mx1,ls.L+rs.mx2,rs.mx1});
      i.mx2=std::max(ls.mx2,rs.mx2+ls.L-ls.R);
    }
    
    • 1

    信息

    ID
    12313
    时间
    1500ms
    内存
    256MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者