P4735 最大異或和 可持久化Trie

2021-10-09 22:49:07 字數 1706 閱讀 3378

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樹,用類似於主席樹的思想,建一顆動態開...