P15496 题解
P15496 & 模拟赛T4
题意:
有两个元素 \(1\) 和 \(0\) 。定义 \((1>0)=1\) 其他为 \(0\) 。
求出一个由 \(n\) 个未知元素组成的表达式(可以有括号),如 \((x>(x>x))\)
你可以给定一组 \(n\) 个 \(x\) 的取值,如 ( \(1,0,0\) ) ,然后询问表达式的结果。
括号表达式:
括号表达式一般用二叉树表示,叶子节点是元素。如 \((x>(x>x))\) 会被表示为:

如此,我们就需要考虑怎么得到一棵树的形态,通过这个形态我们就可以还原出括号序列。
考虑第 \(i\) 个元素放在哪里:
直接想树的结构没有思路,所以假设我们放置好了前 \(i-1\) 个元素,现在考虑第 \(i\) 个元素放在哪里。
首先,第 \(i\) 个元素肯定是插入在右链上。

所以我们要确定具体是插在右链的哪个位置上。
对于一个查询方案而言,为了更好的确定,那么我们希望右链上左边传过来的值是确定的,即 \(1\) ,如下图中所示。
查询时按右边这种方法填就行了。即右链上每个节点的极左儿子赋为 \(1\) ,其余为 \(0\) 。

我们再将 \(i\) 赋为 \(1\) ,思考一下这样会有什么结果:
我们可以得到点 \(i\) 放置的位置的深度的奇偶性。
这是因为左边的 \(1\) 的个数是确定的, 而直接做上去相当于是每一次合并当前答案都取反(\(0→1/1→0\))。然后如果插入了 \(i\) ,可能会导致某一步多取反了一次/保持原样(具体和深度奇偶性有关),而这样会导致结果的变化,故可以推出 \(i\) 这个点的深度的奇偶性。
这样当然还是做不了。然后我们进一步想一想如何才能知道 \(i\) 的具体位置呢?
考虑逐个将右链左边传上来的 \(1\) 改为传上来 \(0\) 。
初始状态:(假设蓝色为实际 \(i\) 挂载的位置 )

改一次后:

改两次后:

改三次后:

注意! 这里答案变了!
通过多搓几组样例后,我们发现当改掉某个右链节点左边传上来的值后,如果答案变了,那么新增的节点就可以通过一个虚点挂在这个节点下面。如上图。
由于我们已经知道了深度的奇偶性,所以先改变 \(0/1\) 个点,使得奇偶性正确,然后每次改变两个点,然后再询问一次。
这样可以节省一半的查询。
这样由于从底往上遍历,且遍历过的点就不会再用了(不是右链了),所以这部分查询总次数大概是 \(\frac{n}{2}+n\) (最后一次查询无法删掉任何东西,但前面的查询了就没用了可以删掉) 。
每个点还需要查询深度奇偶性一次。向上跳总共 \(\frac{3}{2}n\) 次。所以总共 \(\frac{5}{2} n\) 次,刚好能过。

浙公网安备 33010602011771号