NOI2022模拟测试赛(二十二)

link

通道

自己对于二分图构造一个类 prufer 序列。

一个映射方式是合法的,只需要:

  • 一棵生成树能构造出一个 prufer 序列。
  • 能从一个 prufer 序列逆推回整棵树的形态,即过程中不会出现 “找不到” 或者 “找到多个合法解” 的情况。

敢造就敢有!

排列

转化后题意:

给定三个长度同为 n n n 的序列 V , A , B V,A,B V,A,B,保证 V i > 0 V_i>0 Vi>0

求选出一个区间 [ l , r ] [l,r] [l,r],最大化 ( ∑ i = l r V i ) + min ⁡ i = l r ( A i ) + min ⁡ i = l r ( B i ) \left(\sum_{i=l}^rV_i\right)+\min_{i=l}^r(A_i)+\min_{i=l}^r(B_i) (i=lrVi)+mini=lr(Ai)+mini=lr(Bi)

n ≤ 1 0 6 n\leq 10^6 n106

题解:

用数据结构容易做到 O ( n log ⁡ n ) O(n\log n) O(nlogn),略去。此处讲线性做法:

看到区间 min,考虑建笛卡尔树,比如我们先对 A A A 序列建笛卡尔树。

笛卡尔树上一个点代表一段区间 [ L , R ] [L,R] [L,R],且该区间内的任意子区间 [ l , r ] [l,r] [l,r] A min ⁡ A_{\min} Amin 都相同,此时我们只需要考虑 [ L , R ] [L,R] [L,R] 的所有子区间 [ l , r ] [l,r] [l,r] ( ∑ i = l r V i ) + min ⁡ i = l r B i \left(\sum_{i=l}^rV_i\right)+\min_{i=l}^r B_i (i=lrVi)+mini=lrBi 的最大值即可。

一个很重要的观察是:若 L < l ∧ r < R L<l\land r<R L<lr<R,则 [ l , r ] [l,r] [l,r] 必为 B B B 序列笛卡尔树的一个区间。

因为若不是,那么我们可以往两边扩使得 B min ⁡ B_{\min} Bmin 不变且 ( ∑ i = l r V i ) \left(\sum_{i=l}^rV_i\right) (i=lrVi) 变大,直到 [ l , r ] [l,r] [l,r] B B B 序列笛卡尔树上的一个区间或者 l = L l=L l=L r = R r=R r=R 为止。

所以我们先用 B B B 序列笛卡尔树上的所有区间更新一遍答案。这样 A A A 树上我们只需要考虑 l = L l=L l=L r = R r=R r=R 的情况即可。

两种情况是类似的,不妨考虑 l = L l=L l=L,即区间为前缀的情况。

暴力的做法是用单调栈维护出 [ L , R ] [L,R] [L,R] B B B 上前缀最小值的位置,假设它们分别为 p 1 = L , ⋯   , p k p_1=L,\cdots,p_k p1=L,,pk,那么显然 r r r 只可能在 p 2 − 1 , ⋯   , p k − 1 p_2-1,\cdots,p_k-1 p21,,pk1 上取到(为了方便 l = L , r = R l=L,r=R l=L,r=R 的情况我们单独考虑)。

对于非暴力的方法,我们考虑合并两棵子树的单调栈。设左右儿子的 B B B 前缀最小值的单调栈分别为 B L , B R BL,BR BL,BR

显然合并这两个栈是均摊 O ( 1 ) O(1) O(1) 的。但关键是怎么更新答案。

实际上我们只需要对于单调栈上的每一个点 p i p_i pi 求出 s p i + 1 − 1 + B p i s_{p_{i+1}-1}+B_{p_{i}} spi+11+Bpi 的最大值即可。

左右儿子合并时可能会把 B R BR BR 的一段头给弹掉,为了快速得到剩下一段后缀的 s p i − 1 + B p i − 1 s_{p_{i}-1}+B_{p_{i-1}} spi1+Bpi1 最大值,我们还需要另外一个单调栈来维护 s p i − 1 + B p i − 1 s_{p_{i}-1}+B_{p_{i-1}} spi1+Bpi1 的后缀最大值。

记左右儿子维护这玩意后缀最大值对应的单调栈分别为 M L , M R ML,MR ML,MR,那么我们合并两个儿子的整个算法流程如下:

  1. 合并 B L , B R BL,BR BL,BR,过程中会弹掉 B R BR BR 左边的一段,此时对应弹掉 M R MR MR 中属于这一段的部分,并做更新。
  2. 合并 M L , M R ML,MR ML,MR,过程中会弹掉 M L ML ML 右边的一段。

然后你发现我们有可能会对一个单调栈左右都弹,此时需要用一个链表来维护。

总时间复杂度 O ( n ) O(n) O(n)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值