Educational Codeforces Round 76 F 折半枚举

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;
}
posted @ 2019-11-15 11:37  zhangxianlong  阅读(...)  评论(...编辑  收藏