题解:P12290 [蓝桥杯 2024 国 Java A] 基因组合
P12290 [蓝桥杯 2024 国 Java A] 基因组合 题解
题目链接
先考虑对于小蓝先选的情况。
不妨枚举小蓝选哪个数。设小蓝选的数为
那么,小乔为了使结果最小,会选择与
这个问题非常经典,可以使用
先考虑求
然后将正序遍历改为倒序遍历,即可求出
对于所有
第二问也是类似的。将上面全部的最大、最小反过来即可。
于是容易写出代码。
#include<iostream>
using namespace std;
const int N=1e5+5,INF=0x7fffffff;
int n,tot,ans1,ans2=INF;
int a[N],trie[N*30][2],Min[N],Max[N];
void Insert(int x){
int p=0;
for(int i=30;i>=0;i--){
int bit=x>>i&1;
if(!trie[p][bit]){
trie[p][bit]=++tot;
trie[tot][0]=trie[tot][1]=0;
}
p=trie[p][bit];
}
}
int Ask_max(int x){
int p=0,res=0;
for(int i=30;i>=0;i--){
int bit=x>>i&1;
if(!trie[p][!bit]) p=trie[p][bit];
else p=trie[p][!bit],res+=(1<<i);
}
return res;
}
int Ask_min(int x){
int p=0,res=0;
for(int i=30;i>=0;i--){
int bit=x>>i&1;
if(!trie[p][bit]) p=trie[p][!bit],res+=(1<<i);
else p=trie[p][bit];
}
return res;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],Min[i]=INF;
for(int i=1;i<=n;i++){
Min[i]=min(Min[i],Ask_min(a[i]));
Max[i]=max(Max[i],Ask_max(a[i]));
Insert(a[i]);
}
trie[0][0]=trie[0][1]=0;
for(int i=n;i;i--){
Min[i]=min(Min[i],Ask_min(a[i]));
Max[i]=max(Max[i],Ask_max(a[i]));
Insert(a[i]);
}
for(int i=1;i<=n;i++){
ans2=min(ans2,Max[i]);
ans1=max(ans1,Min[i]);
}
cout<<ans1<<' '<<ans2;
return 0;
}