专栏文章

题解:CF2126G2 Big Wins! (hard version)

CF2126G2题解参与者 5已保存评论 4

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
4 条
当前快照
1 份
快照标识符
@miorn2w1
此快照首次捕获于
2025/12/03 00:01
3 个月前
此快照最后确认于
2025/12/03 00:01
3 个月前
查看原文
首先使用单调栈求出每一个数 aia_i 作为最小值的的区间 [li,ri][l_i,r_i]
考虑如何判定一个区间的中位数是否大于等于 vv:将小于 vv 的数映射为 1-1,大于等于 vv 的数映射为 11,区间和大于等于 00 即代表着该区间的中位数大于等于 vv
即对于区间 [li,ri][l_i,r_i][li,i1][l_i,i-1] 的最大后缀和加上区间 [i+1,ri][i+1,r_i] 的最大前缀和,再加上 ii 位置对应的值大于等于 00 就代表着在区间 [li,ri][l_i,r_i] 内存在包含 ii 的子区间使得其中位数大于等于 vv。类似于最大子段和使用线段树维护即可。
这样就有了一个 O(nlog2n)O(n \log^2 n) 做法:使用主席树维护出 v=1,2,3,,nv=1,2,3,\cdots, n 时所对应的线段树,每次 vv 增大即为将序列中的若干个数从 11 单点修改为 1-1。然后枚举每一个数 aia_i,二分 vv,判断 [li,ri][l_i,r_i] 是否满足上述条件即可。
考虑到要求的答案为中位数减最小值,在最小值增大时,中位数也要增大才会变得更优,所以我们可以从小到大枚举每一个数,并同时维护一个数 xx,代表最小值在目前从小到大枚举的数中时,中位数最大是多少。
这样,在枚举新的一个数时,我们只需要每次判断 xx 能否变为 x+1x+1,如果能,就增大 xx,重复这个过程只到 xx 变得尽量大,并更新答案。我们也不再需要可持久化线段树,在 xx 增大 11 的时候顺便进行单点修改即可。
这样做,即使当前的数作为最小值所对应的中位数小于 xx ,我们也不会把答案变得更优,因为一定有之前将中位数更新到 xx,且值小于等于当前数的一个数,答案一定不劣。
时间复杂度 O(nlogn)O(n\log n)

评论

4 条评论,欢迎与作者交流。

正在加载评论...