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 ...
随机推荐
- 前端关于 superSlide.js 使用,一款基于jquery的前端控件
1引用jQuery.js 和 jquery.SuperSlide.js 2 编写HTML ** 以下是默认的HTMl结构,分别是 ".hd" 里面包含ul, ".bd&q ...
- c#基础知识梳理(二)
上期回顾 - https://www.cnblogs.com/liu-jinxin/p/10818256.html 一.变量 一个变量只不过是一个供程序操作的存储区的名字.在 C# 中,每个变量都有一 ...
- robot framework 如何获取隐藏元素的文本,以及可见元素的文本
1.下图是获取可见元素的文本内容,运行后得到:${B_name}=公告管理:假设公告管理不可见,那么${B_name}=‘’(为空)
- vue基本语法概要(一)
先看两种代码,再进行讲解 第一种格式: <template > <div> <div v-for=" item in sites "> < ...
- /Android/sdk/build-tools/21.1.2/aapt'' finished with non-zero exit value 42
相信很多朋友都会遇到 Error:Error: com.android.ide.common.process.ProcessException: org.gradle.process.internal ...
- 6.Redis的事务
Redis的事务(Redis部分支持事务) a)是什么 可以一次执行多个命令,本质是一组命令的集合.一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其它命令插入,不许加塞 b)能干吗 一个( ...
- 8.读写锁ReadWriteLock
/*ReadWriteLock 读写锁*/ private ReadWriteLock lock = new ReentrantReadWriteLock(); lock.readLock().loc ...
- 理解JVM之JAVA运行时内存区域
java运行时内存区域划分为方法区,堆区,虚拟机栈区,本地方法栈,程序计数器.其中方法区跟堆区是线程共享的数据区,其他的是线程私有的数据区. 1.程序计数器 程序计数器(PC)是一块较小的内存,他是存 ...
- 负载均衡之haproxy负载均衡算法及haproxy的工作模式
haproxy负载均衡的算法有如下7种: .roundrobin : 基于权重轮循. static-rr : 基于权重轮循.静态算法,运行时改变无法生效 source : 基于请求源IP的算法.对请求 ...
- 同一个url对应多个视图函数,取第一个视图函数有效
# -*- coding: utf-8 -*- from flask import Flask app = Flask(__name__) @app.route('/') def index(): r ...