带修区间mex

1 x y 把 \(a[x]\) 改成 \(y\).
2 x y 询问区间 \([x,y]\) 的 mex.

part0

polylog做法

整体二分,转换成保留权值 \([vl,vr)\) 的数,带修的区间数颜色.

这个问题可以cdq,总复杂度 \(O(n \log^3 n)\).

update in 2025.8.4(其实我早就知道可以 2log 了,但有点懒得更新,sorry)

可以 \(O(n \log^2 n)\).

考虑所有不含 \(k\) 的极长区间, 共 \(O(n)\) 个, 且单点修改时变化量为 \(O(1)\)

对于每个极长区间 \(l,r,k\) 看作在二维平面 \(x=l,y=r\) 的点上有一个 \(k\)

查询 \(L,R\) 就是找 \(x<=l,y>=r\) 这个区域的最小值, 可以树套树.

part1

分块可做到.

\(O(1)\) 单点修改(只往小改).

\(O(\sqrt n)\) 找第一个小于k的位置.

直接分成根号块然后维护块内最小,查询用块内结果优化暴力扫即可.

但若单点修改任意就没法 \(O(1)\) 修改了.

part2

回顾不带修的扫描线做法.

扫描线的时候维护权值线段树,每个位置记录权值\(v\)最靠右的出现位置,不存在为-inf.

把询问挂在右端点上,从左向右扫描线,扫到时答案为第一个<l的位置,可以线段树二分.

part3

考虑对操作分块,每 \(\sqrt{n}\) 个操作分一块.

如果直接用 part2 的方法再暴力维护修改,复杂度是 \(O(n \sqrt n \log n)\).

这个做法修改和查询不平衡,这启发我们优化.

考察 part1 中的情况,启发我们使用类似回滚莫队的思想.

操作分块后把操作块内的修改作为添加操作加入.(修改可以看作删除一个数+添加一个数,这里先不做删除处理).

建一个 part1 中所述的结构.

然后扫描线,询问挂在右端点上,从右向左扫描线.

这里的操作只有删除,可以 \(O(1)\).

扫到的时候,把这个询问对应时间的删除全部加入,记录操作栈.

查询后用操作栈撤销删除,继续扫即可.

操作分块,单次询问时加入的删除操作只有 \(O(\sqrt n)\) 个.

总复杂度即 \(O(n\sqrt n)\).

posted @ 2023-11-25 23:15  QedDust  阅读(591)  评论(0)    收藏  举报