ZJOI 神仙题!四年三道线段树!
据说毒瘤开题顺序 2 3 1,而且只有数据结构题可做……
身在 GD 的 ZJ 人已经被老家省选虐怕了……
容易发现线段树的棵数永远都是 2i,并且每一棵线段树的结构是一模一样的。
并且复制操作实际上只需要考虑原来的贡献 + 新的贡献即可。
设 fi,p 表示所有 2i 棵线段树中的 p 结点有多少个有标记。
考虑把线段树上所有结点按照一次修改操作的遍历顺序分成五类(没错就是在 Orz Sooke 的题解): 1. 修改涉及了一部分区间的结点,即修改操作走过且接着往儿子中走的结点。 2. 修改涉及了全部区间的结点,且本次被打了标记。 3. 修改未涉及的结点,但在父亲结点被走过时被下推了标记。 4. 修改涉及了全部区间的结点,但本次未被走到过。 5. 其他修改未涉及的结点。
结点 p 属于第 c 类记作 p∈c。
然后先列出几个转移: fi,p={fi−1,p,p∈1fi−1,p+2i−1,p∈2fi−1,p+…,p∈3
写到 3 的时候发现了点严肃的问题:
转移值与祖先中是否有标记有关。
来,直接再设一个 gi,p 表示所有 2i 棵线段树中的 p 结点有多少个所有祖先都没有标记。 $$ fi,p={fi−1,p,p∈1fi−1,p+2i−1,p∈2fi−1,p+2i−1−gi−1,p,p∈32fi−1,p,p∈4∨p∈5gi,p={gi−1,p+2i−1,p∈1gi−1,p,p∈2∨p∈42gi−1,p,p∈3∨p∈5
然后考虑怎么实现。
1,2,3 都有 O(logn) 个,于是直接暴力模拟修改操作即可。
4,5 看起来不可做,其实就是几个区间双倍的操作,打标记处理。
然后维护一下 f 的总和,滚动 i 维。
注意分清楚题目中的线段树和维护 DP 值的线段树……下推标记多多益善……
代码:
1 |
|