codeforces-1285D(字典树)
Dr. Evil Underscores
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
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 \(max_{1≤i≤n}\)(ai⊕X).
Input
The first line contains integer n (1≤n≤\(10^5\)).
The second line contains n integers a1,a2,…,an (0≤ai≤\(2^{30}\)−1).
Output
Print one integer — the minimum possible value of max1≤i≤n(\(a_i\)⊕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=3.
In the second sample, we can choose X=5.
题意:给定n个数,要求你设定一个X,这个X与每个数异或后所得的结果最小,并且这个X要尽可能的大,输出这个异或出的最小的结果
思路:采用异或字典树即可,由于题目给定的数据范围是 \(2^{30}-1\),所以只需要将字典树的深度设置为31位即可,
因为异或是不进位的加法运算,将每一个数都构造为30位的二进制存放在字典树中,接着从第29位开始向低位构造异或出的结果,因为要求异或结果ans尽可能的小而构造的X尽可能的大,对于第i位,如果在n个数中第i位0和1都存在,那么ans就一定要加上\(2^i\),之后再对子树答案取min即可。入宫第i位只有0或1,直接取反就行了。时间复杂度是O{logmax\(a_i\)}
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#include<vector>
using namespace std;
using ll = long long;
const ll N = 1e6;
const double PI = acos(-1.0);
#define Test ll tesnum;tesnum = read();while(tesnum--)
ll read();
int cnt = 1;
int tri[1<<21][2];
void insert(int x)
{
int p = 1;
for(int i = 29; i >= 0; i--){
int ch = (x >> i)&1;
if(tri[p][ch]==0){
tri[p][ch] = ++cnt;
}
p = tri[p][ch];
}
}
int solve(int modo,int now)
{
if(modo==-1)
return 0;
if(tri[now][0]==0)
return solve(modo-1,tri[now][1]);
else
if(tri[now][1]==0)
return solve(modo-1,tri[now][0]);
else
return (1<<modo)+min(solve(modo-1,tri[now][1]),solve(modo-1,tri[now][0]));
}
int main()
{
int n,a;
cin>>n;
while(n--)
{
cin>>a;
insert(a);
}
cout<<solve(29,1)<<endl;
return "BT7274", NULL;
}
inline ll read() {
ll hcy = 0, dia = 1;char boluo = getchar();
while (!isdigit(boluo)) {if (boluo == '-')dia = -1;boluo = getchar();}
while (isdigit(boluo)) {hcy = hcy * 10 + boluo - '0';boluo = getchar();}
return hcy * dia;
}