[CodeForces - 1285D] Dr. Evil Underscores 异或 01Trie树

题目链接:https://codeforces.com/problemset/problem/1285/D

【题目描述】

Today, as a friendship gift, Bakry gave Badawy nn integers a1,a2,,ana1,a2,…,an and challenged him to choose an integer XX such that the value max1in(aiX)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 max1in(aiX)max1≤i≤n(ai⊕X).

Input

The first line contains integer nn (1n1051≤n≤105).

The second line contains nn integers a1,a2,,ana1,a2,…,an (0ai23010≤ai≤230−1).

Output

Print one integer — the minimum possible value of max1in(aiX)max1≤i≤n(ai⊕X).

Examples
input
Copy
3
1 2 3
output
Copy
2
input
Copy
2
1 5
output
Copy
4
Note

In the first sample, we can choose X=3X=3.

In the second sample, we can choose X=5X=5.

 

 

【题意】:给你一堆数,你可以自己选一个X,使这堆数与X异或后的最大值最小。输出这个最小值

【题解】:从高位到低位看,如果这一位0和1都存在,那答案肯定加这一位。

然后分成这一位是0的集合与这一位是1的集合,看剩下的几位如何最小,对两个结果取min
如果只有0或1存在,那答案这一位为1,直接看下几位。
爆搜的话可以用vector存,这里用01trie存的递归起来很方便。

【AC代码】

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int const maxn=4e6;
 4 int tr01[maxn][2],x;
 5 int len,check[maxn],n,tot;
 6 void insert(int x){//01树构建
 7     int ex,v=0;
 8     for(int i=29;i>=0;i--){
 9         ex=!!(x&(1<<i));
10         if(tr01[v][ex])v=tr01[v][ex];
11         else{
12             tr01[v][ex]=++tot;
13             v=tot;
14         }
15     }
16 }
17 void init(){
18     tot=0;
19     memset(tr01,0,sizeof(tr01));
20 }
21 int work(int x,int wei){
22     /*
23     如果这一位0和1都存在,那答案肯定加这一位。
24     然后分成这一位是0的集合与这一位是1的集合,看剩下的几位如何最小,对两个结果取min
25     如果只有0或1存在,那答案这一位为1,直接看下几位。
26     爆搜的话可以用vector存,这里用01trie存的递归起来很方便。
27 
28     */
29     if(!tr01[x][0]&&!tr01[x][1])return 0;
30     if(tr01[x][0]==0) return work(tr01[x][1],wei-1);
31     if(tr01[x][1]==0) return work(tr01[x][0],wei-1);
32     return (1<<wei)+min(work(tr01[x][1],wei-1),work(tr01[x][0],wei-1));
33 }
34 int main(){
35     scanf("%d",&n);
36     init();
37     for(int i=1;i<=n;i++){
38         scanf("%d",&x);
39         insert(x);
40     }
41     // cout<<tot<<endl;
42     printf("%d\n",work(0,29));
43     return 0;
44 }

 

posted @ 2020-08-14 15:03  conver^_^  阅读(194)  评论(0编辑  收藏  举报