Educational Codeforces Round 76 F 折半枚举
https://codeforces.com/contest/1257/problem/F
题意:
数组a,找到一个x使得a中每一个元素异或x后“二进制中1的个数”相同。
数组长度100,数字大小2^30。
思路:
折半枚举答案X,如分为X前15位和后15位。之后我们再枚举期望的“相同个数”是多少,通过hash看看能不能满足就好了。
代码:
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define PB push_back
#define LL long long
#define pii pair<int,int>
#define MEM(x,y) memset(x,y,sizeof(x))
#define bug(x) cout<<"debug "#x" is "<<x<<endl;
#define FIO ios::sync_with_stdio(false);
#define ALL(x) x.begin(),x.end()
#define LOG 20
const int inf =1e9;
const int maxn =3e5+7;
const int mod = 1e9+7;
const int N=3e5+7;
int n,m;
int a[maxn];
int main(){
FIO;
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
map<vector<int>,int> hash_;
const int mask=(1<<18)-1;
for(int i=0;i<(1<<18);i++){
vector<int> t(n);
for(int j=0;j<n;j++){
t[j]=__builtin_popcount((a[j]&mask)^i);
}
hash_[t]=i;
}
for(int i=0;i<(1<<12);i++){
vector<int> t(n),p(n);
int mx=0;
for(int j=0;j<n;j++){
t[j]=__builtin_popcount((a[j]>>18)^i);
mx=max(t[j],mx);
}
for(int sum=mx;sum<=30;sum++){
for(int j=0;j<n;j++){
p[j]=sum-t[j];
}
if(hash_.count(p)){
cout<<hash_[p]+(i<<18)<<endl;
return 0;
}
}
}
cout<<"-1"<<endl;
return 0;
}