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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章