解法
桁ごとに独立に計算する. 上の桁から決めていく.
vector \(a\) に対して,各元の \(2^{k}\) の係数が \(0,1\) で分類する. それらを \(a^{(0,k)}, a^{(1,k)}\) とおく. \(f(k, a)\) を,\(x\) を動かしたときの \(x \oplus a\) の \(2^{j} , j \leq k\) の部分に対する答え とする.
Case: \(a^{(0,k)}\) が空のとき:
\(x\) の \(2^{k}\) の係数を \(1\) にすれば,\(x \oplus a^{(1,k)}\) の全ての元に対して, \(2^{k}\)の係数は \(0\) になる.
Case: \(a^{(1,k)}\) が空のとき:
\(x\) の \(2^{k}\) の係数を \(0\) にすれば,\(x \oplus a^{(0,k)}\) の全ての元に対して, \(2^{k}\)の係数は \(0\) になる.
Case : どちらも空でないとき
\(min(f(k-1,a^{(0,k)}),f(k-1,a^{(1,k)}))+2^{k}\) となる.
注意
演算の優先順位に注意. << と + は,+ 優先.
使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"
int main() {
ll n;
cin >> n;
vll a(n); rep(i,n) { cin >> a[i]; }
auto f = [&](auto f, ll k , vll &b) -> ll {
if(k == -1){
return 0;
}
vvll v(2);
rep(i,b.size()){ // rem: not i in b.size()
ll x = (b[i]>>k&1);
v[x].push_back(b[i]);
}
if(v[0].size() == 0) return f(f, k-1, v[1]);
if(v[1].size() == 0) return f(f, k-1, v[0]);
return min(f(f, k-1, v[0]), f(f, k-1, v[1])) + (1LL<<k);
};
cout << f(f, 35, a) << endl;
return 0;
}