Codeforces 1285D Dr. Evil Underscores (R1800)
問題
要素数の数列が与えられます。としてあり得る値の最小値を求めてください。
制約
考察
とします。の先頭桁がなるべく小さくなるようにするのがよいので、を先頭桁から決めていきます。 今桁目を見ているとして、次の3つの場合があります。
(1) 桁目の数が全てのとき
の桁目をにすることで、の桁目をにすることができます。
(2) 桁目の数が全てのとき
の桁目をにすることで、の桁目をにすることができます。
(3) 桁目にとの両方があるとき
の桁目をのどちらにしても、の桁目はになります。桁目がであるような数の集合を、であるような数の集合をとします。の桁目をにした場合、に含まれる数ととのxorが最大値になることはないので、次の桁を決めるときはだけを考えれば良いです。同様にの桁目をにした場合は、だけを考えれば良いです。両方試してよかった方を選びます。
(3)で両方試すと計算量が指数爆発する気がしますが、各数が見られる回数は桁数に等しいので、図を書くと各桁ごとにかかっていると分かるので、計算量はです。
#include<bits/stdc++.h> using namespace std; using Lint=long long; int rec(int pos,vector<int> &a) { if(pos<0) return 0; vector<int> S,T; for(auto I:a) (~I>>pos&1? S:T).push_back(I); if(S.empty()) return rec(pos-1,T); if(T.empty()) return rec(pos-1,S); return (1<<pos)+min(rec(pos-1,T),rec(pos-1,S)); } int main() { int N; cin>>N; vector<int> a(N); for(int i=0;i<N;i++) cin>>a[i]; cout<<rec(29,a)<<endl; }
感想
バチャ中には解けませんでした。この解法も頭を少しよぎりましたが、計算量が指数爆発すると思って除外してしまいました。シンプルな問題設定でとても好きです。