题目
在 C F \tt CF CF 原题面中,并没有要求 x ≤ y x\le y x≤y 。在一些博客中却有这一条。
题目概要
定义
f
(
i
,
j
)
=
⨁
x
=
i
j
x
f(i,j)=\bigoplus_{x=i}^{j}x
f(i,j)=⨁x=ijx 对于
Q
Q
Q 个询问
⟨
l
,
r
⟩
\lang l,r\rang
⟨l,r⟩ 求出最大的
f
(
a
x
,
a
y
)
(
a
x
≤
a
y
∧
x
,
y
∈
[
l
,
r
]
)
f(a_x,a_y)(a_x\le a_y\wedge x,y\in[l,r])
f(ax,ay)(ax≤ay∧x,y∈[l,r]) 。
思路
维护异或前缀和,则 f f f 可以被表示为两个前缀的异或值。
回滚莫队。我们需要两个 0-1 t r i e \text{0-1 }\tt trie 0-1 trie ,一个维护 a x − 1 a_x-1 ax−1 的异或前缀和,另一个维护 a x a_x ax 的异或前缀和。显然,前者是用于作为较小的 a a a ,后者则相反。
由于你不知道在 “ 小 t r i e \tt trie trie ”(维护 a x − 1 a_x-1 ax−1 的异或前缀和的那一个) 上找到的 a x a_x ax 究竟是不是比自己小,所以,对于每一个 t r i e \tt trie trie 的节点,维护一个子树内所有终态对应的 a x a_x ax 的最小值( “ 小 t r i e \tt trie trie ” 要用)与最大值( “ 大 t r i e \tt trie trie ” 要用)。
每次加入一个点,就在前面的 t r i e \tt trie trie 中寻找到,与这个前缀和异或起来最大的。然后更改 t r i e \tt trie trie 。
之所以要回滚,正是因为最值 a a a 是很难直接撤销的。你得把修改过的 t r i e \tt trie trie 节点保存一下,回滚的时候撤销。
补充:如果有要求 x ≤ y x\le y x≤y ,那么只需要修改一下即可。左边加入时,只能作为较小的;右边加入时,只能作为最大的。可能还要简单一点?
代码
I: I must show the code!
My Brain: No, You've explained it clearly.