开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 28 天,点击查看活动详情
今天我无情的copy了acw周赛,不然太菜了。
题目
给定一个长度为 n� 的整数序列 a1,a2,…,an�1,�2,…,��。
请你找到一个非负整数 X�,使得 max1≤i≤n{ai⊕X}max1≤�≤�{��⊕�} 的值尽可能小,其中 ⊕⊕ 表示按位异或。
输出 max1≤i≤n{ai⊕X}max1≤�≤�{��⊕�} 的最小可能值。
输入格式
第一行包含整数 n�。
第二行包含 n� 个整数 a1,a2,…,an�1,�2,…,��。
输出格式
一个整数,表示 max1≤i≤n{ai⊕X}max1≤�≤�{��⊕�} 的最小可能值。
数据范围
前 33 个测试点满足 1≤n≤31≤�≤3。
所有测试点满足 1≤n≤1051≤�≤105,0≤ai≤230−10≤��≤230−1。
输入样例1:
3
1 2 3
输出样例1:
2
输入样例2:
2
1 5
输出样例2:
4
分析
这题就是字典树+dfs,先对所有数建一个0-1字典树,然后假设一个30位的数,全为0,然后看son[p][0]要是不存在,那这位就取son[p][1],如果son[p][1]不存在,就取son[p][0],如果都存在,就分而治之并且+上1<<cnt.
代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
#include <cmath>
#include <unordered_map>
#include <stack>
#include <queue>
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;
typedef pair<int,int> PII;
typedef pair<string,int> PSI;
int gcd(int x,int y){
return y?gcd(y,x%y):x;
}
ll qmi(ll x,ll y,int mod){
ll res=1;
while(y){
if(y&1) res=res*x%mod;
y>>=1;
x=x*x%mod;
}
return res;
}
const int N=4000100;
int son[N][2];
int a[N],idx=1,n;
#define ll long long
inline void insert(int x){
int p=0;
for(int i=30;i>=0;i--){
int u=(x>>i&1);
if(!son[p][u]) son[p][u]=++idx;
p=son[p][u];
}
}
ll dfs(int cnt,int p){
if(cnt==-1) return 0ll;
if(!son[p][0]) return dfs(cnt-1,son[p][1]);
else if(!son[p][1]) return dfs(cnt-1,son[p][0]);
else return min(dfs(cnt-1,son[p][0]),dfs(cnt-1,son[p][1]))+(1ll<<cnt);
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
insert(a[i]);
}
cout<<dfs(30,0)<<"\n";
return 0;
}