给你n个数,a1....an,求(ai+aj)^ak最大的值,i不等于j不等于k
思路:先建字典树,暴力i,j每次删除他们,然后贪心找k,再恢复i,j,每次和答案取较大的,就是答案,有关异或的貌似很多都用字典树,也是醉了
/*Problem : 5536 ( Chip Factory ) Judge Status : Accepted RunId : 15506230 Language : G++ Author : qianbi08*/ #include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include <algorithm> #include<cstring> using namespace std; const int maxn=300005; int node[maxn][2],cnt,re[maxn]; int a[1005]; int newnode() { ++cnt; node[cnt][0]=node[cnt][1]=-1; re[cnt]=0; return cnt; } void update(int v,int d) { int u=0; for(int i=30; i>=0; --i) { int c=(v>>i)&1; if(node[u][c]==-1) node[u][c]=newnode(); u=node[u][c]; re[u]+=d; } } int getans(int v) { int u=0,ans=0; for(int i=30; i>=0; --i) { if(u==-1)break; int c=(v>>i)&1; if(node[u][c^1]!=-1&&re[node[u][c^1]]) { ans=(ans|(1<<i)); u=node[u][c^1]; } else u=node[u][c]; } return ans; } int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); cnt=0; node[0][0]=node[0][1]=-1; re[0]=0; for(int i=1; i<=n; ++i) scanf("%d",&a[i]),update(a[i],1); int ans=0; for(int i=1; i<n; ++i) { update(a[i],-1); for(int j=i+1; j<=n; ++j) { update(a[j],-1); ans=max(ans,getans(a[i]+a[j])); update(a[j],1); } update(a[i],1); } printf("%d\n",ans); } return 0; }
时间: 2024-10-10 05:31:56