Codeforces 1208F Bits And Pieces 位运算 + 贪心 + dp
题意:给你一个序列a, 问a[i] ^ (a[j] & a[k])的最大值,其中i < j < k。
思路:我们考虑对于每个a[i]求出它的最优解。因为是异或运算,所以我们从高位向低位枚举,如果这一位a[i]是0,我们就在a[i]的右边找两个位置让它们按位与起来这位是1。那么,我们贪心的保留可以通过按位与凑出某个二进制数的最靠右的两个位置。这个可以通过dp的方式预处理出来。之后,我们枚举每一个数a[i],先找出它的哪些位是0,之后从高位到低位枚举,判断这一位是否可以变成1。如果之前已经加上的位再加上这一位可以被凑出来,那么我们就加上这一位。在所有的a[i]得出的答案中去最大值即可。
代码:
#include <bits/stdc++.h>
#define pii pair<int, int>
#define INF 0x3f3f3f3f
#define db double
using namespace std;
const int maxn = 2000010;
pii dp[1 << 21];
int a[maxn];
void update(int mask, int val) {
if(dp[mask].second == 0) {
dp[mask].second = val;
return;
}
if(dp[mask].first == val || dp[mask].second == val) return;
if(val > dp[mask].second) {
dp[mask].first = dp[mask].second;
dp[mask].second = val;
} else if(val > dp[mask].first) {
dp[mask].first = val;
}
}
void merge(int mask1, int mask2) {
if(dp[mask2].first != 0) update(mask1, dp[mask2].first);
if(dp[mask2].second != 0) update(mask1, dp[mask2].second);
}
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
update(a[i], i);
}
for (int i = 0; i < 21; i++) {
for (int j = 0; j < (1 << 21); j++) {
if((j >> i) & 1) {
merge(j ^ (1 << i), j);
}
}
}
int ans = 0;
for (int i = 1; i <= n; i++) {
int mask = 0, tmp = (1 << 21) - 1 - a[i];
for (int j = 20; j >= 0; j--) {
if((tmp >> j) & 1) {
if(dp[mask ^ (1 << j)].first > i && dp[mask ^ (1 << j)].second != 0) {
mask ^= (1 << j);
}
}
}
if(dp[mask].first > i && dp[mask].second != 0) ans = max(ans, a[i] ^ mask);
}
printf("%d\n", ans);
}
Codeforces 1208F Bits And Pieces 位运算 + 贪心 + dp的更多相关文章
- Codeforces 1208F - Bits And Pieces(高维前缀和)
题面传送门 题意:求 \(\max\limits_{i<j<k}a_i|(a_j\&a_k)\). \(1\leq n \leq 10^6,1\leq a_i\leq 2\time ...
- Codeforces F. Bits And Pieces(位运算)
传送门. 位运算的比较基本的题. 考虑枚举\(i\),然后二进制位从大到小考虑, 对于第\(w\)位,如果\(a[i][w]=1\),那么对\(j.k\)并没有什么限制. 如果\(a[i][w]=0\ ...
- CodeForces165E 位运算 贪心 + 状压dp
http://codeforces.com/problemset/problem/165/E 题意 两个整数 x 和 y 是 兼容的,如果它们的位运算 "AND" 结果等于 0,亦 ...
- BZOJ4245 ONTAK2015 OR-XOR 【位运算+贪心】*
BZOJ4245 ONTAK2015 OR-XOR Description 给定一个长度为n的序列a[1],a[2],…,a[n],请将它划分为m段连续的区间,设第i段的费用c[i]为该段内所有数字的 ...
- 【洛谷P2114】起床困难综合征 位运算+贪心
题目大意:给定 N 个操作,每个操作为按位与.或.异或一个固定的数字,现在要求从 0 到 M 中任选一个数字,使得依次经过 N 个操作后的值最大. 题解:位运算有一个重要的性质是:位运算时,无进位产生 ...
- 【Luogu】2114起床困难综合征(位运算贪心)
题目链接 这题真是恶心死我了. 由于位运算每一位互不干涉,所以贪心由大到小选择每一位最优的解,但是要判断一下边界,如果选择该解使得原数>m则不能选择. 代码如下 #include<cstd ...
- BZOJ-3668 起床困难综合症 位运算+贪心
faebdc学长杂题选讲中的题目...还是蛮简单的...位运算写的不熟练... 3668: [Noi2014]起床困难综合症 Time Limit: 10 Sec Memory Limit: 512 ...
- POJ 3764 The xor-longest Path trie树解决位运算贪心
http://poj.org/problem?id=3764 题意 : 一颗树,每个边有个值,在树上找一条简单路径,使得这条路径上的边权异或值最大 先找到所有节点到一点的距离 , 显然dis( x ...
- The number of set(位运算+状态dp)一道十分美妙的题目哦!!!!!!
Given you n sets.All positive integers in sets are not less than 1 and not greater than m.If use the ...
随机推荐
- [洛谷P2296] NOIP2014 寻找道路
问题描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...
- 流氓软件修改IE主页的解决方法
运行regedit HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main 修改以下url Default_Page_URL Firs ...
- 20180805-Java ByteArrayOutputStream类
下面的例子演示了ByteArrayInputStream 和 ByteArrayOutputStream的使用: import java.io.* public class ByteStreamTes ...
- Jmeter中if 控制器的使用
使用if控制器有两种方式:1.不勾选“interpret condition as variable expression”直接输入我们需要判断的表达式即可,判断表达式为真时,执行if控制器下的请求, ...
- Oracle 一条sql插入多条数据
Oracle一次插入多条数据. 表结构: create table aa ( ID NUMBER(11) PRIMARY KEY, NAME VARCHAR2(20) ) 第一种方式: insert ...
- PHP 调试 - Xdebug
PHP 调试指南.pdf PHP 程序员的调试技术 根据要调试的对象的不同,采取的方法也不一样: 调试 web 应用:对于 web 应用,可以在浏览器中安装插件,或者在 IDE 中设置,下面的设置二选 ...
- JS基础(下)
事件DOM Event 更多事件请查询h3c htmldom参考手册 event onclick() :当点击时 onfocus() :获得焦点时 :当点击某个区域时触发,如点击输入框 onblu ...
- _exit和exit的区别
在linux的标准库函数中,有一套称作高级I/O的函数,我们熟知的printf .fopen .fread .fwrite都在此列,他们也被称作缓冲I/O.其特征是对应每一个打开的文件,都存在一个缓冲 ...
- PHP点滴记录
mysqli_fetch_object() //取得当前行,并作为对象返回 mysqli_fetch_row() //从结果集中取得一行,并作为枚举数组返回 mysqli_fetch_array() ...
- C#后台去除字符串最后一个字符
string str = "a,b,c,"; int length = str.length; //获取字符串长度 str = str.substring(0,length-1); ...