https://codeforces.com/contest/1257/problem/F
思路
首先如果暴力做的话, 就是 100*2^30, 肯定 T。
考虑 meet in the mid , 将 30 位的数拆分成前 15 位和后 15 位。
然后暴力枚举 x 异或数组 a 的所有状态, 用 map 存起来, 然后考虑前 15 位和后 15 位组合起来能否满足要求。 (比如前 15 位中 a1 比 a2 多修改了一个 1, 那么在后 15 位中需要找到a2 比 a1 多修改一个 1 的进行组合)
代码
#include<bits/stdc++.h>
#define ios std::ios::sync_with_stdio(false)
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define pb push_back
using namespace std;
const int N = 2e5 + 10, MOD = 1e9+7, inf = 0x3f3f3f3f;
int a[N];
map<vector<int>, int> mp;
int gao(int x){
int res = 0;
while(x){
res += x & 1;
x >>= 1;
}
return res;
}
signed main()
{
ios;
int n;
cin >> n;
rep(i,1,n){
cin >> a[i];
}
vector<int> vec,tmp;
rep(i,0,(1 << 15)-1){
vec.clear();
rep(j,1,n){
vec.pb(gao(a[j]%(1<<15) ^ i));
}
mp[vec] = i;
}
rep(i,0,(1<<15)-1){
vec.clear();
rep(j,1,n){
vec.pb(gao((a[j]>>15) ^ i));
}
rep(j,0,15){
tmp.clear();
rep(k,0,n-1){
tmp.pb(j - vec[k]);
}
if (mp.count(tmp)){
int x = mp[tmp];
cout << (i << 15 | x) << '\n';
return 0;
}
}
}
cout << -1 << '\n';
return 0;
}