Trie+位运算
和前面差不多的题,但是注意一下i、j、k都是不同的,在找异或最大值的时候要把i、j从树上删除,枚举完后再加回来
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int N = 1010; 6 int a[N],son[N*32][2],idx,cnt[N*32];//易错: i和j不同,并且i删除后要插回来 7 void insert_t(int x) 8 { 9 int p = 0; 10 for(int i=31;~i;i--){ 11 int t = x>>i&1; 12 if(!son[p][t]) son[p][t] = ++idx; 13 p = son[p][t]; 14 cnt[p]++; 15 } 16 } 17 int query(int x)//查询最大值 18 { 19 int p = 0,ans = 0; 20 for(int i=31;~i;i--){ 21 int t = x>>i&1; 22 if(son[p][!t]&&cnt[son[p][!t]]){ 23 p = son[p][!t]; 24 ans+=1<<i; 25 }else if((son[p][!t]&&!cnt[son[p][!t]])||!son[p][!t]){ 26 p = son[p][t]; 27 } 28 } 29 return ans; 30 } 31 void deletes(int x) 32 { 33 int p = 0; 34 for(int i=31;~i;i--){ 35 int t = x>>i&1; 36 p = son[p][t]; 37 cnt[p]--; 38 } 39 } 40 int main() 41 { 42 // freopen("in.txt","r",stdin); 43 int t; 44 scanf("%d",&t); 45 while(t--){ 46 memset(cnt,0,sizeof(cnt)); memset(son,0,sizeof(son)); idx = 0; 47 int n,ans = 0,maxn = 0; 48 scanf("%d",&n); 49 for(int i=1;i<=n;i++) { scanf("%d",&a[i]);insert_t(a[i]); } 50 for(int i=1;i<=n;i++){ 51 deletes(a[i]); 52 for(int j=i+1;j<=n;j++){ 53 int x = a[i]+a[j]; 54 deletes(a[j]); 55 ans = query(x); 56 maxn = max(maxn,ans); 57 insert_t(a[j]); 58 } 59 insert_t(a[i]); 60 } 61 printf("%d\n",maxn); 62 } 63 return 0; 64 }