题意简述
一棵高度为 $n$ 的满二叉树(节点数为 $2^{n+1}-1$),用一个 $[0,2^n)$ 的数 $X$ 表示一条根到叶子的路径(从最高位开始,为0
则走左儿子,否则走右儿子)。
初始 $X = 0$,有两种操作共 $q$ 个:
- 将 $X$ 改为 $(X + 2^C) \bmod 2^n$,然后从根出发走到叶子。
- 询问当前有多少个节点至少被访问一次。
$n,q\le 10^5$。
主要思路
考虑一次新增的节点数,不难发现是 $n$ 减去新的 $X$ 与之前所有数的 lcp 的最大值。
不难发现这个最大值必然在新 $X$ 的前驱或后继中取得。
考虑加上 $2^C$ 的操作,实质上是把前面的一段1
赋为0
,把一个0
赋为1
。
于是每个修改操作只会改变均摊 $O(1)$ 个位置。
于是可以上棵可持久化线段树维护每个位的值。
那么如何比较大小?
可以在可持久化线段树上二分第一个两数不同的位置,然后 $O(\log n)$ 比较。
那么我们希望能够 $O(1)$ 比较两棵线段树上的一个区间是否完全相等。
这个哈希一下就好了。
于是我们获得了一个 $O(\log n)$ 比较大小的方法,再套个set
维护前驱后继就 $O(n\log^2n)$ 走了。
然后这题被出到模拟赛里有人被卡常了,所以是 CC 太快还是 CC 数据水啊(
参考代码
1 |
|