传送门

题意: 给你 n 个数 a[ 1 ]  ~ a[ n ], n <= 100; 让你找一个 x , 使得 a[ 1 ] = a[ 1 ] ^ x ~ a[ n ] = a[ n ] ^ x;

   且 a[ 1 ] ~ a[ n ] 的二进制位上的 1 的个数相等。  每个 a[ i ] <= 2^30;

解: a[ i ] <= 2 ^ 30; 那么x也不会超过 2^30; 那我们暴力枚举两个 2 ^ 15;

    分别枚举 x 异或上 a[ i ] 的 低 15, 和 x 异或上 a[ i ] 的高15位;

    然后我们用 cnt[ 0 ][ 1 ]代表 a[ 1 ] 这个数 异或上你枚举的这个x后, 的低15位上 1 的个数。

    cnt[ 1 ][ 1 ] 代表 a[ 1 ] 这个数 异或上你枚举的 这个 x后, 的高 15 位上 1 的个数。

    那我们要找到一个 x,使得 cnt[ 0 ][ 1 ] + cnt[ 1 ][ 1 ]  = cnt[ 0 ][ 2 ] + cnt[ 1 ][ 2 ] = ...... = cnt[ 0 ][ n ] + cnt[ 1 ][ n ];

    那我们是 cnt[ 0 ] 和 cnt[ 1 ] 分开枚举的嘛。   

    那当我们枚举低15位时。我们就 开个 vector 存一下, cnt[ 0 ] 的 后一位减去前一位。 即  vector 存的是

    cnt[ 0 ][ 2 ] - cnt[ 0 ][ 1 ], cnt[ 0 ][ 3 ] - cnt[ 0 ][ 2 ]; ........ cnt[ 0 ][ n ] - cnt[ 0 ][ n - 1 ];

  那我们枚举高15位时。 我们的 vector 存的就是 -1 * cnt[ 1 ]的后一位减去前一位。 即

   -1 * (  cnt[ 1 ][ 2 ] - cnt[ 1 ][ 1 ] ) ........ -1 * (  cnt[ 1 ][ n ] - cnt[ 1 ][ n - 1 ]  );

  然后, 当 cnt[ 0 ] 的vector 和 cnt[ 1 ] 的vector 是一样的时候, 就意味着, 每个数的 cnt[ 0 ] + cnt[ 1 ] 是相等的。

  因为, cnt[ 0 ][ 2 ] - cnt[ 0 ][ 1 ] = -1 * (  cnt[ 1 ][ 2 ] - cnt[ 1 ][ 1 ]  ); 即

  cnt[ 0 ][ 2 ] + cnt[ 1 ][ 2 ] = cnt[ 0 ][ 1 ] + cnt[ 1 ][ 1 ];

  所以, 我们就找到 x 了, 我们开个 map, 存一下 每个 vector 对应的 状态 (statu);就行了。

#include <bits/stdc++.h>
#define LL long long
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define INF 0x3f3f3f3f
#define inf 0x3f3f3f3f3f3f3f3f
#define mem(i, j) memset(i, j, sizeof(i))
#define pb push_back
using namespace std;
int ans = -, n;
map < vector< int >, int > mp;
vector< int > Q;
int a[];
void dfs1(int num, int statu) {
if(num > ) {
Q.clear();
for(int i = ; i <= n; i++) {
Q.push_back(__builtin_popcount((statu ^ a[i]) % ( << )));
}
for(int i = ; i < n; i++) {
Q[i - ] = Q[i] - Q[i - ];
}
Q.pop_back();
if(!mp[Q]) mp[Q] = statu;
return ;
}
dfs1(num + , statu);
dfs1(num + , statu | ( << (num - )));
}
void dfs2(int num, int statu) {
if(num > ) {
Q.clear();
for(int i = ; i <= n; i++) {
///__builtin_popcount(x) 用于计算x的二进制位上1的个数。
Q.push_back(__builtin_popcount(statu ^ (a[i] >> )));
}
for(int i = ; i < n; i++) {
Q[i - ] = - * (Q[i] - Q[i - ]);
}
Q.pop_back(); /// 弹出最后一个元素。
if(mp[Q]) {
ans = mp[Q] | (statu << );
}
return ;
}
dfs2(num + , statu);
dfs2(num + , statu | ( << (num - )));
}
int main() {
scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
}
dfs1(, ); dfs2(, );
printf("%d\n", ans);
return ;
}

  

F. Make Them Similar ( 暴力折半枚举 + 小技巧 )的更多相关文章

  1. Codeforces 912E Prime Gift ( 二分 && 折半枚举 && 双指针技巧)

    题意 : 给你 N ( 1 ≤ N ≤ 16 ) 个质数,然后问你由这些质数作为因子的数 ( 此数不超 10^18 ) & ( 不一定需要其因子包含所给的所有质数 ) 的第 k 个是什么 分析 ...

  2. Atcoder Grand Contest 020 F - Arcs on a Circle(DP+小技巧)

    Atcoder 题面传送门 & 洛谷题面传送门 一道难度 unavailable 的 AGC F 哦 首先此题最棘手的地方显然在于此题的坐标可以为任意实数,无法放入 DP 的状态,也无法直接计 ...

  3. 【枚举+小技巧】【TOJ4115】【Find the number】

    题目大意 找到一个最小的奇数 约数个数为n 结果mod10^9+7 根据 约数个数=(p1+1)*(p2+1)............ 将n 枚举分解成连乘式.(枚举个数,dfs) 比较大小 log ...

  4. HDU OJ 5317 RGCDQ( 2015多校联合训练第3场) 暴力打表+小技巧

    题目连接:Click here 题意:在一个[L,R]内找到最大的gcd(f[i],f[j])其中L<=i<j<=R,f[x]表示i分解质因数后因子的种类数.eg:f[10]=2(1 ...

  5. Codeforces 912 E.Prime Gift (折半枚举、二分)

    题目链接:Prime Gift 题意: 给出了n(1<=n<=16)个互不相同的质数pi(2<=pi<=100),现在要求第k大个约数全在所给质数集的数.(保证这个数不超过1e ...

  6. (容量超大)or(容量及价值)超大背包问题 ( 折半枚举 || 改变 dp 意义 )

    题意 : 以下两个问题的物品都只能取有且只有一次 ① 给你 N 个物品,所有物品的价值总和不会超过 5000, 单个物品的价格就可达 10^10 ,背包容量为 B ② 给你 N (N ≤ 40 ) 个 ...

  7. 折半枚举——poj3977

    暴力搜索超时,但是折半后两部分状态支持合并的情况,可用折半枚举算法 poj3977 给一个序列a[],从里面找到k个数,使其和的绝对值最小 经典折半枚举法+二分解决,对于前一半数开一个map,map[ ...

  8. NYOJ 1091 超大01背包(折半枚举)

    这道题乍一看是普通的01背包,最最基础的,但是仔细一看数据,发现普通的根本没法做,仔细观察数组发现n比较小,利用这个特点将它划分为前半部分和后半部分这样就好了,当时在网上找题解,找不到,后来在挑战程序 ...

  9. POJ 3977 Subset(折半枚举+二分)

    SubsetTime Limit: 30000MS        Memory Limit: 65536KTotal Submissions: 6754        Accepted: 1277 D ...

随机推荐

  1. Eclipse一些技巧

    1:测试某个测试溢出,修改堆内存大小 // 模拟内存溢出 -Xms10m -Xmx10m private static void mockOOM() { List list = new ArrayLi ...

  2. Scratch 3.0,新在哪里?

    大家期待已久的Scratch 3.0,已经上线一段时间了. 学生们可轻松通过连接WeDo2.0和EV3机器人 进行scratch编程学习啦! 或许有些朋友还不太了解Scratch,没关系,小乐今天就为 ...

  3. SAS学习笔记26 方差分析

    对于多于两组(k>2)样本均数的比较,t检验不再适用,方差分析(analysis of variance, ANOVA)则是解决上述问题的重要分析方法.方差分析由R.A.Fisher(1923) ...

  4. Intercity Travelling CodeForces - 1009E (组合计数)

    大意: 有一段$n$千米的路, 每一次走$1$千米, 每走完一次可以休息一次, 每连续走$x$次, 消耗$a[1]+...+a[x]$的能量. 休息随机, 求消耗能量的期望$\times 2^{n-1 ...

  5. Luogu4022 CTSC2012熟悉的文章(广义后缀自动机+二分答案+动态规划+单调队列)

    对作文库中的串建出广义SAM,然后显然可以二分答案,二分之后考虑暴力dp,设f[i]为前i位最长匹配长度,显然有f[i]=max(f[i-1],f[j]+i-j) (i-j>=l&&am ...

  6. poj 2406 求最短重复字串

    题解: KMP中next数组的巧妙运用.在这里我们假设这个字符串的长度是len,那么如果len可以被len-next[len]整除的话,我们就可以说len-next[len]就是那个最短子串的长度为什 ...

  7. 取代Ajax.BeginForm的ajax使用方法

    原文:取代Ajax.BeginForm的ajax使用方法 一.前提概要 Asp.net core中已经取消了Ajax.BeginForm,也不会计划出ajax tag helper,所以得利用插件jq ...

  8. JS OOP -04 JS中的公有成员,私有成员和静态成员

    JS中的公有成员,私有成员和静态成员 a.实现类的公有成员 b.实现类的私有成员 c.实现类的静态成员 a.实现类的公有成员 之前定义的任何类型成员都属于公有成员的范畴,该类的任何实例都对外公开这些属 ...

  9. 【原创】大叔经验分享(85)ssh秘钥之创建和使用

    一 创建秘钥 1 Macbook $ ssh-keygen -t rsaGenerating public/private rsa key pair.Enter file in which to sa ...

  10. wstngfw中配置squid

    wstngfw中配置squid Squid是一个缓存 Internet 数据的软件,其接收用户的下载申请,并自动处理所下载的数据.当一个用户想要下载一个主页时,可以向 Squid 发出一个申请,要 S ...