abc j xor min

170 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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;

}