小清新线段树


Luogu P3792 由乃与大母神原型

增强版是 Luogu P5278。

对于这题, 一段区间 [l,r] 是值域上连续的一段等价于 max(l~r) - min(l~r) = r - l 且区间内没有相同的数。

关于区间内有没有相同的数, 有一个套路是维护这个数上一次出现的位置 pre, 若区间内的 pre 的 min 在左端点左边,那么区间内没有同样的数。

提交记录见此:【提交记录

代码年代久远,比较丑。

NOI2016 区间

无解显然很好判断, 以下讨论有解:

首先从大到小枚举方案中区间长度的最大值 mx, 显然对于每个 mx 都有一个最大的 mi (此方案中区间长度的最小值)使得存在一个合法方案, 这个 mi 显然随 mx 减小而减小, 于是只要维护一个区间加查询区间最大值的线段树就好了。

多判点特殊情况可以写得很舒服。

提交记录

HEOI2013 Segment

李超线段树模板, 李超线段树的思路是当前区间只保留优势最大的线段, 代码很好理解。

提交记录

Luogu P5607 Ynoi2013 无力回天 NOI2017

考虑设 bi = ai xor ai-1, 即异或意义下的差分。

那么就有异或意义下的前缀和,ai = b1 xor b2 xor ... xor bi

类似地, 对于 a[l,r] 中的某个数 ak, 可以用 al xor bl+1 xor bl+2 xor ... xor ak 来表示, a[l,r] 不能表示的, al ∪ b[l+1,r] 显然也不能表示(因为 al ∪ b[l+1,r] 就是用 a[l,r] 构成的)。

即, al ∪ b[l+1,r] 和 a[l,r] 的表示能力相同(本质相同)。

那么就可以修改的时候双点修改, 查询的时候区间合并+一次插入。

提交记录

ZJOI2010 基站选址

设 f(i,j) 表示假设只有前 i 个村庄,在第 i 个村庄建第 j 个基站, 最小的费用。

\[f(i,j) = \min_{j-1\le k<i} \{f(k,j-1) + cost(k,i)\} \]

cost(k,i) 的意义比较显然。

考虑外层从小到大枚举 j, 内层从小到大枚举 i, 拆分转移式子并用数据结构维护(拆 cost, cost(k,i) 拆成 [k+1,i-1] 的补偿(cost1)和在 i 建造的建造费(cost2), 显然只需要维护 f + cost1 作为转移到后面的转移值)。

对于一个村庄 i, 可以简单地计算出能覆盖其的左右边界 [li,ri], 其中 li,ri 均为村庄的标号。

考虑 f(i) 转移到 f(k)(i<k), [i+1,k-1] 中有些村庄需要补偿, 有些不需要, 条件是:对于村庄 i, 若 k > ri, 则对于所有 i < li, 转移的时候都要对村庄 i 进行补偿。

于是在考虑完 ri 这个村庄的时候,对 [1,li-1] 的转移值都加上村庄 i 的补偿就好了。

只需要区间加区间求最小值的线段树。

总复杂度 \(O(kn\log n)\) 就可以过了。

提交记录

posted @ 2021-03-07 11:17  xwmwr  阅读(125)  评论(0编辑  收藏  举报