子陣列的最大異或和
陣列異或和的定義:把陣列中所有的數異或起來得到的值。給定乙個整型陣列arr,其中可能有正、有負,有零,求其中子陣列的最大異或和。
輸入描述:
輸出包含兩行,第一行乙個整數n(1
≤n≤1
05
)n(1 \leq n \leq 10^5)
n(1≤n≤
105)
,代表陣列arr長度,第二個n個整數,代表陣列arr
(−10
9≤ar
ri≤1
09
)arr(-10^9 \leq arr_i \leq 10^9)
arr(−1
09≤a
rri
≤109
)。輸出描述:
輸出乙個整數,代表其中子陣列的最大異或和。
示例1輸入
4
3 -28 -29 2
輸出7
說明這個子陣列的異或和為7,是所有子陣列中最大的
備註:
時間複雜度o(n
long
2n)o
o(nlong_2n)o
o(nlon
g2n
)o,額外空間複雜度o(n
long
2n
)o(nlong_2n)
o(nlon
g2n
)。題解:這題有乙個基礎模型最大異或對,思想就是將數字變成二進位制插入到trie樹,然後對二進位制中的每一位數字,從高位開始盡可能的往相反方向走,這樣獲得的異或值才能盡可能的大。
回到這題,這題是求子陣列的最大異或和,而陣列的字首異或和有這樣乙個規律:
設 x or
[i]=
a[1]
⊕a[2
]⊕..
.⊕a[
i]
xor[i] = a[1] \oplus a[2] \oplus ... \oplus a[i]
xor[i]
=a[1
]⊕a[
2]⊕.
..⊕a
[i] ,則子陣列 arr
[i..
j]
arr[i..j]
arr[i.
.j] 的異或和為:xor
[j]⊕
xor[
i−1]
xor[j] \oplus xor[i-1]
xor[j]
⊕xor
[i−1
] 於是我們可以這樣做:求以每個元素作為子陣列結尾的子陣列的最大異或和,通過將 xor
[1],
xor[
2],.
..,x
or[i
−1
]xor[1], xor[2], ..., xor[i-1]
xor[1]
,xor
[2],
...,
xor[
i−1]
分別插到 trie 樹中,然後查詢 xor
[i
]xor[i]
xor[i]
與 trie 樹中的元素的最大異或值,此時就變成了上述最大異或對模型。
注意:從二進位制的高位開始找相反方向涉及到貪心思想,因為越是高位不同,異或的結果更大。
這題有乙個坑點:此題數字有正有負。。。假設我們把數字變成 32 位,這意味著我們必須考慮第 31 位符號位,負數往負數方向走,正數往正數方向走,這樣才能保證異或值是盡可能的大,所以查詢時需要先處理一下符號位。
**:
#include
#include
#include
using
namespace std;
const
int n =
100000
;const
int m = n *32+
1;int trie[m][2
], idx;
void
add(
int x )
}int
query
(int x )
p = trie[p]
[u];
for(
int i =
30; i >=0;
--i )
else p = trie[p]
[u];
}return ret;
}int
main
(void
)printf
("%d\n"
, ret)
;return0;
}
最大異或和
問題描述 給出n個整數,多組詢問求乙個給出的數與這n個數中的乙個數的最大異或的值。輸入格式 第一行乙個整數n,表示有個數字。第二行n個正整數。第三行乙個整數m,表示m個詢問。第四行m個整數,表示m個詢問的整數。輸出格式 共m行,對於每個詢問輸出最大的異或值。輸入樣例 43 5 6 7 31 4 7 ...
最大異或和
展開 題目描述 給定乙個非負整數序列 初始長度為nn。有 mm 個操作,有以下兩種操作型別 a x 新增操作,表示在序列末尾新增乙個數 xx,序列的長度 n 1n 1。q l r x 詢問操作,你需要找到乙個位置 pp,滿足l le p le rl p r,使得 a p oplus a p 1 op...
3261 最大異或和
給定乙個非負整數序列,初始長度為n。有m個操作,有以下兩種操作型別 1 ax 新增操作,表示在序列末尾新增乙個數x,序列的長度n 1。2 qlrx 詢問操作,你需要找到乙個位置p,滿足l p r,使得 a p xor a p 1 xor xor a n xor x 最大,輸出最大是多少。第一行包含兩...