HDU-5536 Chip Factory (字典树)

题目大意:给n个数,编号为1~n,取三个编号不同的数,使表达式(a+b)^c的值最大。

题目分析:将这n个数按二进制位建立一棵trie。枚举i、j的和,查询亦或最大值,但在查询之前要把i、j在trie中删除,查询完毕后再插入trie。

ps:用数组实现trie会超时,因为每次test case之前都要初始化数组,非常耗时。

代码如下:

# include<iostream>
# include<cstdio>
# include<cmath>
# include<vector>
# include<list>
# include<queue>
# include<map>
# include<set>
# include<cstring>
# include<algorithm>
using namespace std;
# define LL long long

const int N=1000;
const int INF=1000000000;
const double inf=1e20;

struct Node
{
	int cnt;
	Node *son[2];
	Node(){
		cnt=0;
		son[0]=son[1]=NULL;
	}
};
Node *root;
int a[N+5];
int n;

void update(int x)
{
	Node *p=root;
	for(int i=30;i>=0;--i){
		int k=(x&(1<<i))>0?1:0;
		if(p->son[k]==NULL)
			p->son[k]=new Node();
		++(p->son[k]->cnt);
		p=p->son[k];
	}
}

void erase(LL x)
{
	Node *p=root;
	for(int i=30;i>=0;--i){
		int k=(x&(1<<i))>0?1:0;
		--(p->son[k]->cnt);
		p=p->son[k];
	}
}

int query(int x)
{
	int res=0;
	Node *p=root;
	for(int i=30;i>=0;--i){
		int k=(x&(1<<i))>0?1:0;
		if(p->son[k^1]!=NULL&&p->son[k^1]->cnt>0){
			res|=(1<<i);
			p=p->son[k^1];
		}else{
			p=p->son[k];
		}
	}
	return res;
}

void delTree(Node *p)
{
	if(p==NULL) return ;
	delTree(p->son[0]);
	delTree(p->son[1]);
	delete p;
}

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		root=new Node();
		for(int i=0;i<n;++i){
			scanf("%d",a+i);
			update(a[i]);
		}
		int ans=0;
		for(int i=0;i<n;++i){
			erase(a[i]);
			for(int j=i+1;j<n;++j){
				erase(a[j]);
				ans=max(ans,query(a[i]+a[j]));
				update(a[j]);
			}
			update(a[i]);
		}
		printf("%d
",ans);
		delTree(root);
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/20143605--pcx/p/5475559.html