zoukankan      html  css  js  c++  java
  • F. Make Them Similar

    题目链接:

    题意:给出一个有n个数的数组a,问是否能找到一个x满足b[i]=a[i]^x。而这个b数组里面所有元素的二进制1的个数都是相等的

    a[i]<(2^30)-1  

    思路:

    由数据范围可知,x的范围一定在2^30内,那么我们很容易想到meet in the middle !!!对于30位的搜索折半复杂度为2^15随随便便就能AC啦(硬是WA了4发,还写了巨长时间emmm)

    首先我们预处理出前15位的状态,然后跟a数组全部元素做异或操作,那么对于15位后的我们可以取模去掉防止造成影响。

    然后我们能得到当前状态异或前15位得到的每个新的元素的1的个数,那么我们统计一下后一位减当前位的差值(为什么这样我一会再说)

    那么标记这个 vector数组,这个开个map就行了,顺便还能把当前状态放进去

    那么之后就是枚举后15位了,同理我们能得到一个后15位的数组,对于这个数组我们用当前位减去后一位。

    那么对于两个互补的数组,他们存在一个关系,一个用后一位减当前位,一个用当前位减后一位,得到的数组会是相同的。

    证明其实也不难想:如果他们是互补的,那么他们的顺序一定是相反的。所以就有这个条件!!!

    那么如果有满足这样的要求我们就可以得到答案了

    详情请见代码!

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define re register
    #define pb push_back
    #define fi first
    #define se second
    const int N=2e6+10;
    void read(int &a)
    {
        a=0;int d=1;char ch;
        while(ch=getchar(),ch>'9'||ch<'0')
            if(ch=='-')
                d=-1;
        a=ch^48;
        while(ch=getchar(),ch>='0'&&ch<='9')
            a=(a<<3)+(a<<1)+(ch^48);
        a*=d;
    }
    int a[N],n;
    vector <int> v;
    map <vector <int>,int> vis;
    int ans=-1;
    void dfs1(int i,int now)
    {
        if(i==15)
        {
            v.clear();
            for(re int j=1;j<=n;j++) v.pb(__builtin_popcount((now^a[j])%(1<<15)));
            for(re int j=1;j<n;j++) v[j-1]=v[j]-v[j-1];
            v.pop_back();
            if(!vis.count(v)) vis[v]=now;
            return;
        }
        dfs1(i+1,now);
        dfs1(i+1,now|(1<<i));
    }
    void dfs2(int i,int now)
    {
        if(i==15)
        {
            v.clear();
            for(re int j=1;j<=n;j++) v.pb(__builtin_popcount(now^(a[j]>>15)));
            for(re int j=1;j<n;j++) v[j-1]-=v[j];
            v.pop_back();
            if(vis.count(v)) ans=vis[v]|(now<<15);
            return;
        }
        dfs2(i+1,now);
        dfs2(i+1,now|(1<<i));
    }
    int main()
    {
        read(n);
        for(re int i=1;i<=n;i++) read(a[i]);
        dfs1(0,0);dfs2(0,0);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    RecycleView点击事件
    RecycleView 的使用 (CardView显示每个小项)
    wine
    git
    ubuntu 装机
    tar 压缩为多个文件&解压缩
    make error: makefile:4: *** missing separator. Stop
    python中的PEP是什么?怎么理解?(转)
    博客园如何转载别人的文章(转)
    信息熵
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/11870284.html
Copyright © 2011-2022 走看看