01字典树+贪心 Codeforces Round #613 (Div. 2) D题 Dr. Evil Underscores

Dr. Evil Underscores

Today, as a friendship gift, Bakry gave Badawy n integers a1,a2,…,an and challenged him to choose an integer X such that the value max1≤i≤n(ai⊕X) is minimum possible, where ⊕ denotes the bitwise XOR operation.

As always, Badawy is too lazy, so you decided to help him and find the minimum possible value of max1≤i≤n(ai⊕X).


题目大意:给你 n 个数,让你找一个数 x ,这个 x 分别异或 n 个数,求最大最小值;

看到异或最大最小值,首先想到01字典树了;这个算法的存数是没有贪心思维的,但是当你要求异或值时,就有贪心思维了;

但是这题还不是模板,要知道,把这 n 个数拆成二进制的形式,如果某个二进制位0和1都有,那么这个二进制位取0或取1都是会贡献值的;反之,如果只有1或0,那么取1或0就可以避免贡献值了,所以按此思路,由高位向低位贪心就行;

代码:

#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=100100;
const int M=5000100;
const LL mod=9987;
int tr[N*32][2],rt;
void insert(int x){
	int k=0;
	for(int i=30;i>=0;i--){
		int d=(x>>i)&1;
		if(!tr[k][d]) tr[k][d]=++rt;
		k=tr[k][d];
	}
}
int dfs(int now,int dep){
	int k0=tr[now][0],k1=tr[now][1];
	if(!k0&&!k1) return 0;
	if(!k0&&k1) return dfs(k1,dep-1);
	if(k0&&!k1) return dfs(k0,dep-1);
	return (1<<dep)+min(dfs(k1,dep-1),dfs(k0,dep-1));
}
int main(){
	int n;scanf("%d",&n);
	for(int i=1;i<=n;i++){
		int x;scanf("%d",&x);
		insert(x);
	} 
	printf("%d\n",dfs(0,30));	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章