# 子數組的最大異或和問題

CSDN：子數組的最大異或和問題

## 暴力解

``````int[] eor = new int[arr.length];
``````

``````    eor[0] = arr[0];
for (int i = 1; i < n; i++) {
eor[i] = eor[i - 1] ^ arr[i];
}
``````

i ~ j 之間的異或和等於 `eor[j] ^ eor[i-1]`(i > 0)，所以

``````    for (int i = 1; i < n; i++) {
max = Math.max(max, eor[i]);
for (int j = i; j < n; j++) {
max = Math.max(max, eor[j] ^ eor[i - 1]);
}
}
``````

``````  public static int maxEor1(int[] arr, int n) {
int[] eor = new int[arr.length];
int max = arr[0];
eor[0] = arr[0];
for (int i = 1; i < n; i++) {
eor[i] = eor[i - 1] ^ arr[i];
}
for (int i = 1; i < n; i++) {
max = Math.max(max, eor[i]);
for (int j = i; j < n; j++) {
max = Math.max(max, eor[j] ^ eor[i - 1]);
}
}
return max;
}
``````

## 最優解

eor[0..0] = 1011

eor[0..1] = 1010

eor[0..2] = 0101

eor[0..3] = 1111

eor[0..4] = 0010

eor[0..5] = 0110

eor[2] = 0101

eor[2] 期待和它符號位一樣爲0的值，緊着高位（由於前面28都是0，所以不存在和它符號不一樣的，只看最後4位，

``````  public static int maxEor(int[] arr, int n) {
int[] eor = new int[arr.length];
int max = 0;
eor[0] = arr[0];
for (int i = 1; i < n; i++) {
eor[i] = eor[i - 1] ^ arr[i];
}
Trie trie = new Trie(eor);
trie.add(eor[0]);
for (int i = 1; i < n; i++) {
max = Math.max(max, trie.get(eor[i]));
}
return max;
}

public static class Trie {
public Node head;

public Trie(int[] arr) {
head = new Node();
for (int eor : arr) {
add(eor);
}
}

public void add(int num) {
Node cur = head;
for (int bit = 31; bit >= 0; bit--) {
int i = ((num >>> bit) & 1);
if (cur.next[i] == null) {
cur.next[i] = new Node();
}
cur = cur.next[i];
}
}

public int get(int eor) {
int expect = 0;
Node cur = head;
for (int bit = 31; bit >= 0; bit--) {
// 符號位期待一樣的
// 非符號位期待相反的
int expectBit = bit == 31 ? ((eor >>> bit) & 1) : (eor >>> bit & 1 ^ 1);
if (cur.next[expectBit] != null) {
expect = ((expectBit << bit) | expect);
cur = cur.next[expectBit];
} else {
expectBit = (expectBit ^ 1);
cur = cur.next[expectBit];
expect = ((expectBit << bit) | expect);
}
}
return expect ^ eor;
}
}

public static class Node {
public Node[] next = new Node[2];
}
``````