题意:就是求max((si+sj)^sk)
思路:就是直接建01字典树,在上面求异或,对于枚举的ij,我们先在字典树中进行删除,然后在插入进去(调一下午也没调出来,不知道错哪里了)
代码:
#include <bits/stdc++.h> using namespace std; const int maxn=1000+10; int n; int a[maxn]; int sz; int trie[100000+10][2]; int cnt[100000+10]; void init() { sz=1; memset(trie[0],0,sizeof(trie[0])); } void Insert(int v,int d) { int u=0; for(int i=30;i>=0;i--){ int c=(v>>i)&1; if(!trie[u][c]){ trie[sz][0]=trie[sz][1]=0; cnt[sz]=0; trie[u][c]=sz++; } u=trie[u][c]; cnt[u]+=d; } } int solve(int x) { int res=0,u=0; for(int i=30;i>=0;i--){ int c=(x>>i)&1; if(trie[u][c^1] && cnt[trie[u][c^1]]){ res|=(1<<i); u=trie[u][c^1]; } else u=trie[u][c]; } return res; } int main() { int T; scanf("%d",&T); while(T--){ init(); int n; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); Insert(a[i],1); } int ans=0; for(int i=1;i<=n;i++){ Insert(a[i],-1); for(int j=i+1;j<=n;j++){ Insert(a[j],-1); ans=max(ans,solve(a[i]+a[j])); Insert(a[j],1); } Insert(a[i],1); } printf("%d\n",ans); } return 0; }
来源:https://www.cnblogs.com/lalalatianlalu/p/9740923.html