考虑将所有数用二进制表示
若xor值
最大 那么$u^v$ 中 v的每一位尽量和u相反
但是现实很骨感
我们建一颗Trie树
若这一位能找到相反的 那么直接用相反的
否则只能用相同的
为什么最大?
我们插入时是从高到低插入的
那么我们看三个01串
(1)111100000
(2)011100000
(3)100011111
那么(1)^(2)大 还是 (1)^(3) 大?
正确性显然
还有什么不懂的看代码
Author: Miku_𝓜𝓪𝓼𝓽𝓮𝓻
Date: 2021/5/26
#include <bits/stdc++.h>
using namespace std ;
int read(int x = 0,bool f = false,char ch = getchar()) {
for (;!isdigit(ch);ch = getchar()) f |= ch == '-' ;
for (;isdigit(ch);ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48) ; return f ? ~ x + 1 : x ;
}
class Trie {
private :
int Tp ;
Trie *son[2] ;
public :
Trie(int x):Tp(x){
for (int i = 0 ; i < 2 ; ++i ) son[i] = NULL ;
}
void insert(Trie* &Root,int x) {
Trie* p = Root ;
for (int i = 30 ; ~i ; --i ) {
int arr = x >> i & 1 ;
if (p -> son[arr] == NULL) p -> son[arr] = new Trie(0) ;
p = p -> son[arr] ;
}
}
int search(Trie* &Root,int x) {
int ans = 0 ;
Trie* p = Root ;
for (int i = 30 ; ~i ; --i ) {
int arr = x >> i & 1 ;
if (p -> son[!arr] == NULL) {
p = p -> son[arr] ;
} else {
ans |= 1 << i ;
p = p -> son[!arr] ;
}
} return ans ;
}
} ;
const int N = 1e6 + 5 ;
int n , Ans ;
int a[N] ;
signed main() {
Trie* Answer = new Trie(0) ;
n = read() ;
for (int i = 1 ; i <= n ; ++i ) a[i] = read() , Answer -> insert(Answer,a[i]) ;
for (int i = 1 ; i <= n ; ++i ) {
Ans = max(Ans,Answer -> search(Answer,a[i])) ;
}
return printf("%d\n",Ans) , 0 ;
}
米神哟!