P4735 最大異或和

2022-03-04 03:07:47 字數 1689 閱讀 5352

給定乙個非負整數序列,初始長度為n。

有m個操作,有以下兩種操作型別:

a x:新增操作,表示在序列末尾新增乙個數x,序列的長度n+1。

q l r x:詢問操作,你需要找到乙個位置p,滿足l≤p≤r,使得: a[p]⊕a[p+1]⊕...⊕a[n]⊕x最大,輸出最大是多少。

輸入格式:

第一行包含兩個整數 n,m,含義如問題描述所示。

第二行包含 n個非負整數,表示初始的序列a。

接下來 m行,每行描述乙個操作,格式如題面所述。

輸出格式:

假設詢問操作有 t個,則輸出應該有 t行,每行乙個整數表示詢問的答案。

輸入樣例#1: 

5  5

2 6 4 3 6

a 1

q 3 5 4

a 4q 5 7 0

q 3 6 6

輸出樣例#1: 

4

56

對於測試點 1−2,n,m≤5。

對於測試點 3−7,n,m≤80000。

對於測試點 8−10,n,m≤300000。

其中測試點 1, 3, 5, 7, 9保證沒有修改操作。

0≤a[i]≤107。

solution:

本題可持久化trie樹板子。

可持久化trie樹這東西和主席樹很像,思路就是大量利用先前版本,並建立字首式的結構。

對於本題,我們直接用可持久化trie樹維護異或字首和。考慮詢問的$[p,n]$的異或和就是$s_n\;xor\;s_$,那麼我們就是要在$[l-1,r-1]$這段區間內找到乙個值$s_p$與$s_n\;xor\;x$相異或值最大,那麼還是貪心的從高位到低位去查,只不過像主席樹一樣每次都是作字首減法得到當前區間的節點資訊。至於插入操作,每次都是在末尾加數,那麼只要往trie樹中加入新的異或字首和就好了。

時間複雜度$o(n\log n)$。

**:

/*

code by 520 -- 9.27

*/#include

#define il inline

#define ll long long

#define re register

#define for(i,a,b) for(re int (i)=(a);(i)<=(b);(i)++)

#define bor(i,a,b) for(re int (i)=(b);(i)>=(a);(i)--)

using

namespace

std;

const

int n=600005

;int

n,m,cnt,sum,rt[n];

struct

nodet[n*30

];char s[2

];int

gi()

void ins(int &rt,int lst,int d,int

v)int query(int l,int r,int d,int v,int

ans)

intmain()

}return

0;

}

P4735 最大異或和

題目鏈結 給定乙個非負整數序列,初始長度為n。有m個操作,有以下兩種操作型別 a x 新增操作,表示在序列末尾新增乙個數x,序列的長度n 1。q l r x 詢問操作,你需要找到乙個位置p,滿足l p r,使得 a p a p 1 a n x最大,輸出最大是多少。輸入格式 第一行包含兩個整數n,m,...

P4735 最大異或和

p4735 最大異或和 可持久化trie 據n n 0,我們可以把問題轉化為字首異或和 設為s i 也就是求 s n s p 的最大值 顯然,這是經典的trie上貪心問題。但是詢問次數過多,我們總不能每次都建一棵完整的樹。注意到,對於每次詢問我們所需的trie都只有很小的不同。於是我們就可以用可持久...

P4735 最大異或和

點我跳轉 給定乙個非負整數序列 a 初始長度為 n 有 m 個操作,有以下兩種操作型別 1 a x 新增操作,表示在序列末尾新增乙個數 x 序列的長度 n 增大 1 2 q l r x 詢問操作,你需要找到乙個位置 p 滿足 l p r 使得 a p xor a xor xor a n xor x ...