Processing math: 100%

「CodeChef WALKBT」Walks on the binary tree

题意简述

CodeChef WALKBT

一棵高度为 n 的满二叉树(节点数为 2n+11),用一个 [0,2n) 的数 X 表示一条根到叶子的路径(从最高位开始,为0则走左儿子,否则走右儿子)。

初始 X=0,有两种操作共 q 个:

  • X 改为 (X+2C)mod2n,然后从根出发走到叶子。
  • 询问当前有多少个节点至少被访问一次。

n,q105

主要思路

考虑一次新增的节点数,不难发现是 n 减去新的 X 与之前所有数的 lcp 的最大值。
不难发现这个最大值必然在新 X 的前驱或后继中取得。

考虑加上 2C 的操作,实质上是把前面的一段1赋为0,把一个0赋为1
于是每个修改操作只会改变均摊 O(1) 个位置。
于是可以上棵可持久化线段树维护每个位的值。

那么如何比较大小?
可以在可持久化线段树上二分第一个两数不同的位置,然后 O(logn) 比较。
那么我们希望能够 O(1) 比较两棵线段树上的一个区间是否完全相等。
这个哈希一下就好了。

于是我们获得了一个 O(logn) 比较大小的方法,再套个set维护前驱后继就 O(nlog2n) 走了。

然后这题被出到模拟赛里有人被卡常了,所以是 CC 太快还是 CC 数据水啊(

参考代码

Related Issues not found

Please contact @OkazakiYumemi to initialize the comment