题意:
给定一个含有一些0/1
变量的后缀表达式,每次询问临时将一个变量的值取反,求此时表达式的值。
分享一个题解区没有的 $O((n+q)\log n)$ 的倍增做法。
首先建立出表达式树。
然后修改一个位置的数的时候,我们发现只会影响它到根节点的路径上的数值,而不会影响到其它节点的数值。
暴力修改太耗时了,于是我们想到了这道题。
考虑倍增。
设 $f_{i,j,k}$ 为第 $i$ 个节点取值为 $k$ 时向上跳 $2^j$ 步后的节点的数值,那么:
${f_{i,j,k}=f_{anc_{j,i-1},j-1,f_{i,j-1,k}}}$,
其中 $anc_{i,j}$ 为第 $i$ 个节点向上跳 $2^j$ 步的节点。
解释一下就是先向上跳 $2^{j-1}$ 步过后,到达 $anc_{i,j-1}$ ,它上面的数值是 $f_{i,j-1,k}$。
再在 $anc_{i,j-1}$ 的取值为 $f_{i,j-1,k}$ 的基础上向上跳 $2^{j-1}$ 步,就是 ${f_{i,j,k}=f_{anc_{j,i-1},j-1,f_{i,j-1,k}}}$ 了。
查询的时候把 $x_i$ 的取值取反,然后倍增跳到根节点,最后根节点的数值就是表达式的值。
就 AC 了。
代码:
1 |
|