2014 百度之星 资格赛 Xor Sum hdu 4825

Xor要每一位都不同才最大,高位优先。可以先建立一颗字典树,32层(其实31层就行)。

每次优先选择位不同的那颗树,如果为空则选择相同。

答案是 每次左移一位+(该位不同1-t,相同则t)


#include<stdio.h>  
#include<string.h>  
#include<iostream>

struct node{  
	int cnt;  
	node *childs[2];  
	node(){  
		cnt=0;  
		for(int i=0;i<2;i++)  
			childs[i]=NULL;  
	}  
};  
node *rt=new node();  
node *cur,*next;  

void insert(char *str){  
	cur=rt;  
	int len=32,t;  
	for(int i=0;i<len;i++){  
		t=str[i]-'0';  
		if(cur->childs[t]==NULL){  
			next=new node();  
			cur->childs[t]=next;  
		}  
		else{  
			next=cur->childs[t];  
		}  
		next->cnt++;  
		cur=next;  
	}  
}  

void search(char *str){  
	long long ans=0;
	cur=rt;  
	int len=32,t;  
	for(int i=0;i<len;i++){  
		t=str[i]-'0';  
		if(cur->childs[1-t]!=NULL){//1-t与t有不同
			ans=ans*2+1-t;
			cur=cur->childs[1-t];
		}
		else{
			ans=ans*2+t;
			cur=cur->childs[t];
		} 
	} 
	printf("%I64d\n",ans);
}  


int main(){  
	int tt,n,m,cases=1,t;
	scanf("%d",&tt);
	while(tt--){
		scanf("%d %d",&n,&m);
		char str[34];str[32]=0;
		for(int i=0;i<n;i++){
			scanf("%d",&t);
			for(int i=0;i<32;i++){
				if((t&(1ll<<i))>0)
					str[31-i]='1';
				else str[31-i]='0';
			}
			insert(str);
		}
		printf("Case #%d:\n",cases++);
		while(m--){
			scanf("%d",&t);
			for(int i=0;i<32;i++){
				if((t&(1ll<<i))>0)
					str[31-i]='1';
				else str[31-i]='0';
			}
			search(str);
		}
		rt->childs[0]=NULL;
		rt->childs[1]=NULL;//递归delete(rt)会超时
	}
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值