F. Make Them Similar ( 暴力折半枚举 + 小技巧 )
题意: 给你 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 ( 暴力折半枚举 + 小技巧 )的更多相关文章
- Codeforces 912E Prime Gift ( 二分 && 折半枚举 && 双指针技巧)
题意 : 给你 N ( 1 ≤ N ≤ 16 ) 个质数,然后问你由这些质数作为因子的数 ( 此数不超 10^18 ) & ( 不一定需要其因子包含所给的所有质数 ) 的第 k 个是什么 分析 ...
- Atcoder Grand Contest 020 F - Arcs on a Circle(DP+小技巧)
Atcoder 题面传送门 & 洛谷题面传送门 一道难度 unavailable 的 AGC F 哦 首先此题最棘手的地方显然在于此题的坐标可以为任意实数,无法放入 DP 的状态,也无法直接计 ...
- 【枚举+小技巧】【TOJ4115】【Find the number】
题目大意 找到一个最小的奇数 约数个数为n 结果mod10^9+7 根据 约数个数=(p1+1)*(p2+1)............ 将n 枚举分解成连乘式.(枚举个数,dfs) 比较大小 log ...
- 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 ...
- Codeforces 912 E.Prime Gift (折半枚举、二分)
题目链接:Prime Gift 题意: 给出了n(1<=n<=16)个互不相同的质数pi(2<=pi<=100),现在要求第k大个约数全在所给质数集的数.(保证这个数不超过1e ...
- (容量超大)or(容量及价值)超大背包问题 ( 折半枚举 || 改变 dp 意义 )
题意 : 以下两个问题的物品都只能取有且只有一次 ① 给你 N 个物品,所有物品的价值总和不会超过 5000, 单个物品的价格就可达 10^10 ,背包容量为 B ② 给你 N (N ≤ 40 ) 个 ...
- 折半枚举——poj3977
暴力搜索超时,但是折半后两部分状态支持合并的情况,可用折半枚举算法 poj3977 给一个序列a[],从里面找到k个数,使其和的绝对值最小 经典折半枚举法+二分解决,对于前一半数开一个map,map[ ...
- NYOJ 1091 超大01背包(折半枚举)
这道题乍一看是普通的01背包,最最基础的,但是仔细一看数据,发现普通的根本没法做,仔细观察数组发现n比较小,利用这个特点将它划分为前半部分和后半部分这样就好了,当时在网上找题解,找不到,后来在挑战程序 ...
- POJ 3977 Subset(折半枚举+二分)
SubsetTime Limit: 30000MS Memory Limit: 65536KTotal Submissions: 6754 Accepted: 1277 D ...
随机推荐
- SQL语句中加中括号[ ]的作用
有些可能是SQL里面的保留字,但是你又用了它做字段名 比如Action,用[Action] 就可以避免这个问题,如果直接Action SQL就要报错了. 解决较长的中文名表名可能会被不识别的问题.
- 怎样理解script标签的defer属性和async属性
如果script标签是引用的外部js文件, 那就会有一个下载js文件这一过程, 为了不因为这个下载过程而阻塞页面解析与渲染, 我们需要一种机制来解决这一问题, 方法之一就是使用 defer和async ...
- 联想U310 安装系统后无法识别机械硬盘处理
过程: 原30G的固态更换成250G的 mSATA固态,去掉机械硬盘,开始在固态里安装系统, 系统用PE登录,安装正版Win7 64B 专业版, 安装结束,接上机械硬盘, *PE下,可以正常识别2块硬 ...
- [转载]Linux 命令详解:./configure、make、make install 命令
[转载]Linux 命令详解:./configure.make.make install 命令 来源:https://www.cnblogs.com/tinywan/p/7230039.html 这些 ...
- 1.volatile关键字 内存可见性
Java JUC 简介 在 Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括 ...
- Bind Mounts and File System Mount Order
When you use the bind option of the mount command, you must be sure that the file systems are m ...
- Flutter中的普通路由与命名路由(Navigator组件)
Flutter 中的路由通俗的讲就是页面跳转.在 Flutter 中通过 Navigator 组件管理路由导航.并提供了管理堆栈的方法.如:Navigator.push 和 Navigator.pop ...
- 我是怎么找到电子书的 - IT篇
转自于:http://my.oschina.net/0757/blog/375908#OSC_h2_8 IT-ebooks http://it-ebooks.info/ http://www.it-e ...
- 虚拟机ipv6环境搭建操作指南
一.vmware的相关配置 (1)点击编辑,选择虚拟网络编辑器 (2)选择带NAT模式的VMnet8网络,点击NAT设置 (3)在NAT设置中启用IPV6 (4)设置好后,点击应用 (5)再选择镜 ...
- sql server 某一列求和
sql server 某一列求和 SELECT 患者来源,设备类型,检查部位,设备名称,convert(char(10),STUDY_DATE,121) as 日期, count(distinct 就 ...