CF1732D 解题报告(mex 相关)
题意:给定集合 \(\{0\}\) 和 \(q\) 次操作,每次操作有两种情况:
- \(+~x\):向集合内插入 \(x\),保证集合里之前没有 \(x\)。
- \(-~x\):在集合中删除 \(x\),保证集合中之前有 \(x\)。
- \(?~k\):求集合的 \(k-\operatorname{mex}\),即最小的不包含在集合内的能被 \(k\) 整除的数。
分析:
先考虑没有删除操作的情况,也就是 D1。
首先暴力做法是 \(O(n^2)\)。
我们想到,当一个数插入时,仅当它是某个 \(k-\operatorname{mex}\) 的时候才会影响,其他的 \(\operatorname{mex}\) 不会被它影响。
那么在每插入一个数的时候把其是 \(k-\operatorname{mex}\) 的 \(k\) 更新一遍,可不可行呢?
理论上不可行,考虑构造 \(1,2,4,...\) 的序列, \(k = 1,2,4,...\),那么时间复杂度还是 \(O(n^2)\)。但是实际上到了 \(10^{18}\) 之后只能构造 \(3, 6, 9, ...\),每次的查询序列会增加 \(1\),因此跑的很不满。加上 cf 的评测机牛逼,能过。
那么我们如果插入暴力维护,询问的时候再从当前标记往后逐一判断,可不可行呢?
首先因为没有删除操作,因此 \(k\) 的标记一旦打到 \(x\),就不会再打到比 \(x\) 小的东西了。因此正确性是对的。
其次这玩意的理论复杂度和上一个一样,不知道为啥跑得更快。
补充:ygg证明了这个算法是 \(O(n \log n)\) 的。