[CodeForces gym 102956 D] Bank Security Unification(位运算优化dp)
problem
cf链接
solution
读完题先直接暴力 dpdpdp 拿出来,dpi=maxj<i{dpj+(fi&fj)}dp_i=\max_{j<i}\big\{dp_{j}+(f_i\&f_j)\big\}dpi=maxj<i{dpj+(fi&fj)}。
谁能优化谁就是爸爸
假设存在 j<k<ij<k<ij<k<i,且 fi&fjf_i\&f_jfi&fj 为 111 的最高二进制位是 ppp,且 fi&fk,fk&fjf_i\&f_k,f_k\&f_jfi&fk,fk&fj 的第 ppp 位也为 111。
那么选择 j,k,ij,k,ij,k,i 肯定比 j,ij,ij,i 跳过 kkk 要优。
因为 fj&fif_j\&f_ifj&fi 比 ppp 更高的位全是 000,而加上 kkk,2p2^p2p 就会计入两次贡献,说不定更高位还要额外0贡献产生,但都一定比只算一次 2p2^p2p 大。
所以我们只需要对于每一个二进制位,记录最近的该位为 111 的数下标即可。
到时候直接用 fif_ifi 二进制也为 111 的那些位置进行转移,转移完后再更新。
dpi=maxfi>>j&1{dpgj+(fi&fgj)}dp_i=\max_{f_i>>j\&1}\big\{dp_{g_j}+(f_i\&f_{g_j})\big\}dpi=maxfi>>j&1{dpgj+(fi&fgj)}。
时间复杂度从 O(n2)O(n^2)O(n2) 锐减成 O(nlogv)O(n\log v)O(nlogv)。
位运算常考察两个点:拆成二进制位独立计算以及高二进制位决定/优先低二进制位。
code
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define maxn 1000005
int n;
int f[maxn], dp[maxn], g[60];signed main() {scanf( "%lld", &n );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &f[i] );for( int i = 1;i <= n;i ++ ) {for( int j = 40;~ j;j -- )dp[i] = max( dp[i], dp[g[j]] + (f[g[j]] & f[i]) );for( int j = 40;~ j;j -- )if( f[i] >> j & 1 ) g[j] = i;}int ans = 0;for( int i = 1;i <= n;i ++ ) ans = max( ans, dp[i] );printf( "%lld\n", ans );return 0;
}
/*
dp[i]=max{ dp[j]+a[i]&a[j] }
consider k(j<k<i) satisfy the highest digit p a[i]&a[j] a[i]&a[k] a[j]&a[k] all 1
it's better to choose j k i instead of j i
calc 2^p twice is bigger than once,of course
we just need to choose the nearest node for each digit
O(n^2)->O(n \log v)
*/
[CodeForces gym 102956 D] Bank Security Unification(位运算优化dp)相关推荐
- 【位运算】解题报告:luoguP4310 绝世好题(位运算优化DP)
题目链接:luoguP4310 绝世好题 这是链接 因为答案只能是由两个在二进制表示下至少有一位同是1的a序列里的数&得到的,最后求子序列的个数 f[i]存的是对于a序列中当前遍历到的数中有几 ...
- Java位运算优化:位域、位图棋盘等
快速小测试:如何重写下面的语句?要求不使用条件判断语句交换两个常量的值. if (x == a) x= b; else x= a; 答案: x= a ^ b ^ x; //此处变量x等于a或者等于b ...
- 【BZOJ4300】绝世好题,位运算相关DP
传送门 思路: 按照每一位来进行DP f[i]f[i]表示最后一个数的第i个二进制为1的最长子序列个数 每次转移时把a[i]a[i]拆成二进制位,然后取数为1的位上f<script type=& ...
- Codeforces Gym 102956 C. Brave Seekers of Unicorns(位运算 + dp)
链接 :C. Brave Seekers of Unicorns 题意: 给你一个数 n (1 ≤ \leq ≤ n ≤ \leq ≤ 1e6),要求出有多少个严格单调递增的序列满足任意三个相邻的数满 ...
- CodeForces - 1368D AND, OR and square sum(位运算+贪心)
题目链接:点击查看 题目大意:给出 n 个数组成的序列 a ,现在可以进行的操作是,任选两个下标 i 和 j ,满足 i != j ,使得: 设 x = a[ i ] , y = a[ j ] a[ ...
- 【CodeForces - 558C】Amr and Chemistry(位运算,bfs,计数,思维,tricks)
题干: Amr loves Chemistry, and specially doing experiments. He is preparing for a new interesting expe ...
- !codeforces 558C Amr and Chemistry-yy题-(位运算相关)
题意:有n个数,每次进行的操作只能是除以2或者乘以2,求这n个数转换成同一个数字所需要的最小的操作步数 分析: 乍一看题目,觉得好难,对于这种每次有两种情况求最后到达的终点的balabala的我就觉得 ...
- 【习题·搜索】[NOIP2009]靶型数独(搜索+剪枝+位运算优化)
题目 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教,Z 博士拿出了他最近发明的&quo ...
- CodeForces - 932G Palindrome Partition(回文自动机+Palindrome Series优化dp)
题目链接:点击查看 题目大意:给出一个长度为偶数的字符串,问将其分割成 k 个子串记为 a[ 1 ] , a[ 2 ] ... a[ k ] ,且满足 a[ i ] == a[ k - i + 1 ] ...
最新文章
- shell中数字大小的比较
- app专项测试(稳定性测试、安全性测试)
- 如何在Spyder中运行spark
- php ip访问mysql什么配置_PHP与MYSQL配合完成IP的存取
- 云函数连接mysql超时_云函数访问MYSQL数据库出错?
- FZU - 2218 Simple String Problem(状压dp)
- 多么痛的领悟--写在领英股票被腰斩之后
- 深度学习,路在何方?
- Div+CSS布局入门教程(四) 页面顶部制作之二
- RestExpress response中addHeader 导致stackOverflow
- ubuntu 的chmod 和 chown
- jlink6.80a烧写序列号(serial number)问题记录
- 怎么制作游戏脚本_自动玩游戏,手游脚本究竟是怎么做的?
- pgAdmin 3 编译安装
- Netch + Connectify 实现代理转全局并共享给其他设备,例如Kindle
- windows屏幕放大镜
- 通过域名访问文件共享服务器,域名访问共享文件夹
- DHTMLXGantt in Flutter DHTMLXGantt
- 【程序哥】分析 网易一元夺宝是否有作弊空间,真像媒体所说的吗?
- 【C语言】指针终结者-初阶
热门文章
- python3抓取图片_通过Python3 爬虫抓取漫画图片
- anaconda和python有什么不一样_黄山毛峰的味道为什么会不一样?
- 中科大计算机是一流学科吗,安徽2017双一流学科排行榜:中国科技大学第一
- tankwar java_TankWar 单机(JAVA版) 版本0.3 画出坦克
- suse linux 文件只可读,SUSE LINUX下文件系统变只读的问题解决
- 文件共享服务器第二部,第二章-构建Samba文件共享服务器.docx
- vector容器中查找某一元素是否存在(牛逼的vector!!!!!!)
- html5访问本地资源,HTML5实现一个访问本地文件的实例今
- java swing 控件拖动_java swing中实现拖拽功能示例
- [数据结构-严蔚敏版]P65离散事件模拟(银行客户的离散事件驱动模拟程序)