-
Chip Factory
- HDU - 5536
- 题目大意:n个数字的序列中,找出三个数字使得(a[i] + a[j])^a[k]最大。
- 题目思路:把这n个数字保存下来建在一个01字典树上面。因为i,j,k三个数字不能重复,所以删去要用的i和j,
- 再在里面找出能和num( a[i]+a[j])异或出的最大值。(注意 (1 << i) & x ? 1 : 0)
-
#include<bits/stdc++.h> using namespace std; #define maxn 1010 #define ll long long int tot,tree[maxn*34][2]; int data[maxn*34],t,n; ll val[maxn*34],ans,s[maxn]; void ins (ll x) { int p=0; for(int i=31; i>=0; i--) { int v=((1<<i)&x?1:0); if(!tree[p][v]) { tree[p][v]=++tot; val[tot]=data[tot]=0; tree[tot][0]=tree[tot][1]=0; } p=tree[p][v]; data[p]++; } val[p]=x; } void updata(ll x,int ad) { int p=0; for(int i=31; i>=0; i--) { int v=((1<<i)&x?1:0); p=tree[p][v]; data[p]+=ad; } } ll query(ll x) { int p=0; for(int i=31; i>=0; i--) { int v=((1<<i)&x?1:0); if(tree[p][v^1]&&data[tree[p][v^1]])p=tree[p][v^1]; else p=tree[p][v]; } return x^val[p]; } int main() { scanf("%d",&t); while(t--) { ans=tot=tree[0][1]=tree[0][0]=0; scanf("%d",&n); for(int i=1; i<=n; i++) { scanf("%lld",&s[i]); ins(s[i]); } for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { if(j==i)continue; updata(s[i],-1); updata(s[j],-1); ans=max(ans,query(s[i]+s[j])); updata(s[i],1); updata(s[j],1); } printf("%lld\n",ans); } return 0; }
Chip Factory HDU - 5536 -01字典树
最新推荐文章于 2019-11-03 12:06:12 发布