n
nn個數字,有操作
在末尾加入乙個數字x
xx詢問[l,
r]
[l,r]
[l,r
]範圍內的乙個p
pp使得ap⊕
ap+1
⊕ap+
2...
⊕an⊕
xa_p\oplus a_\oplus a_...\oplus a_\oplus x
ap⊕ap
+1⊕
ap+2
...
⊕an
⊕x的值最大。
定義si
s_isi
表示字首異或和,那麼其實答案就是求乙個在[l−
1,r−
1]
[l-1,r-1]
[l−1,r
−1]中的乙個s
ps_p
sp使得sn⊕
x⊕sp
s_n\oplus x\oplus s_p
sn⊕x⊕
sp最大。
後面兩個是固定的,考慮如何求s
ps_p
sp,我們知道我們可以用tri
etrie
trie
求靜態的異或和最大,就是按照反方向路徑行走。所以這裡我們用類似於主席樹的方法建立一顆可持久化tri
etrie
trie
。不同的是,我們對於每個節點要維護乙個最大的上限las
tlast
last
(也就是這個節點的子樹中包含的最後的插入的節點),這樣詢問時我們從rtr
rt_r
rtr
出發,避開las
t<
llastla
st<
l的節點就好了。
時間複雜度o(28
n)
o(28n)
o(28n)
#include
#include
#include
using
namespace std;
const
int n=
5e5+
10,w=28;
int n,m,cnt,a[n]
,rt[n]
;int ch[n*40]
[2],last[n*40]
;int
insert
(int x,
int k,
int val,
int id)
int c=
(val>>k)&1
;ch[y]
[c^1
]=ch[x]
[c^1];
ch[y]
[c]=
insert
(ch[x]
[c],k-
1,val,id)
; last[y]
=max
(last[ch[y][0
]],last[ch[y][1
]]);
return y;
}int
ask(
int x,
int k,
int val,
int lim)
intmain()
while
(m--
)else
}return0;
}
P4735 最大異或和(可持久化 trie)
設 sum i 表示前 i 個數的異或和,轉換那個式子為 sum n operatorname x operatorname sum i,i in l 1,r 1 其中的 sum n operatorname x operatorname 是個定值,也就是找乙個 i 使得這個式子最大 由於這是異或運...
P4735 最大異或和 可持久化Trie
給定乙個非負整數序列 初始長度為 n 有 m 個操作,有以下兩種操作型別 a x 新增操作,表示在序列末尾新增乙個數 x 序列的長度 n 1 q l r x 詢問操作,你需要找到乙個位置 p 滿足 l le p le r 使得 a p oplus a p 1 oplus oplus a n oplu...
P4735 最大異或和 01可持久化Trie樹模板
原題 題解 觀察一下式子,將a陣列求乙個異或字首和,其實就是s n x s p 1 的最大值 p l,r 就是區間對乙個數的異或的最最大值。假設我們把這個區間放進trie字典樹中,對於乙個x的詢問,可以用貪心的思想,反著走找到最大值。但是確定出給定區間的trie樹,用類似於主席樹的思想,建一顆動態開...