HDU 5536 Chip Factory (字典树)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kidsummer/article/details/82083385

题意:求max( (a[i] + a[j]) ^ a[k] ) (i, j, k都不相同)  

01字典树。

思路:建一个字典树直接找,每次先删除a[i],a[j]然后找出剩下的与a[i]+a[j]的最大异或和,然后然把a[i],a[j]插回去

亦或和最大值,trie基本操作。

#include <iostream>
#include <cstdio>
#include <cstring>
#define mem(x,v) memset(x,v,sizeof(x)) 
#define go(i,a,b)  for (int i = a; i <= b; i++)
#define og(i,a,b)  for (int i = a; i >= b; i--)
using namespace std;
typedef long long LL;
const double EPS = 1e-10;
const int INF = 0x3f3f3f3f;
const int N = 1e4+10;
int Ac[N*32][2];
int Num[N*32],cnt;
LL End[N*32];
LL a[N];

void Insert(LL z){
	int now = 0;
	og(i,32,0){
		int id = (z & (1ll << i))?1:0;
		if (!Ac[now][id]) Ac[now][id] = ++cnt;
		now = Ac[now][id];
		Num[now]++;
	}
	End[now] = z;
}
void Delete(LL z){
	int now = 0;
	og(i,32,0){
		int id = (z & (1ll<<i))?1:0;
		now = Ac[now][id];
		Num[now]--;
	}
}

LL Query(LL z){
	int now = 0;
	og(i,32,0){
		int id = (z & (1ll << i))? 0:1;
		if (!Ac[now][id] || !Num[Ac[now][id]]) id ^= 1;
		now = Ac[now][id];
	}
	return End[now]^z;
}

int main(){
	int T; cin>>T;
	while(T--){
		int n; scanf("%d",&n);
		LL ans = 0;
		mem(Num,0);
		mem(End,0);
		mem(Ac,0);
		cnt = 0;
		go(i,1,n) scanf("%lld",&a[i]),Insert(a[i]);
		go(i,1,n){
			go(j,i+1,n){
				LL x = a[i] + a[j];
				Delete(a[i]); Delete(a[j]);
				ans = max(ans,Query(x));
				Insert(a[i]); Insert(a[j]);
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/kidsummer/article/details/82083385
今日推荐