problem

cf链接

solution

读完题先直接暴力 dpdpdp 拿出来,dpi=max⁡j<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=max⁡fi>>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(nlog⁡v)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)相关推荐

  1. 【位运算】解题报告:luoguP4310 绝世好题(位运算优化DP)

    题目链接:luoguP4310 绝世好题 这是链接 因为答案只能是由两个在二进制表示下至少有一位同是1的a序列里的数&得到的,最后求子序列的个数 f[i]存的是对于a序列中当前遍历到的数中有几 ...

  2. Java位运算优化:位域、位图棋盘等

    快速小测试:如何重写下面的语句?要求不使用条件判断语句交换两个常量的值. if (x == a) x= b; else x= a; 答案: x= a ^ b ^ x; //此处变量x等于a或者等于b ...

  3. 【BZOJ4300】绝世好题,位运算相关DP

    传送门 思路: 按照每一位来进行DP f[i]f[i]表示最后一个数的第i个二进制为1的最长子序列个数 每次转移时把a[i]a[i]拆成二进制位,然后取数为1的位上f<script type=& ...

  4. Codeforces Gym 102956 C. Brave Seekers of Unicorns(位运算 + dp)

    链接 :C. Brave Seekers of Unicorns 题意: 给你一个数 n (1 ≤ \leq ≤ n ≤ \leq ≤ 1e6),要求出有多少个严格单调递增的序列满足任意三个相邻的数满 ...

  5. CodeForces - 1368D AND, OR and square sum(位运算+贪心)

    题目链接:点击查看 题目大意:给出 n 个数组成的序列 a ,现在可以进行的操作是,任选两个下标 i 和 j ,满足 i != j ,使得: 设 x = a[ i ] , y = a[ j ] a[ ...

  6. 【CodeForces - 558C】Amr and Chemistry(位运算,bfs,计数,思维,tricks)

    题干: Amr loves Chemistry, and specially doing experiments. He is preparing for a new interesting expe ...

  7. !codeforces 558C Amr and Chemistry-yy题-(位运算相关)

    题意:有n个数,每次进行的操作只能是除以2或者乘以2,求这n个数转换成同一个数字所需要的最小的操作步数 分析: 乍一看题目,觉得好难,对于这种每次有两种情况求最后到达的终点的balabala的我就觉得 ...

  8. 【习题·搜索】[NOIP2009]靶型数独(搜索+剪枝+位运算优化)

    题目 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教,Z 博士拿出了他最近发明的&quo ...

  9. CodeForces - 932G Palindrome Partition(回文自动机+Palindrome Series优化dp)

    题目链接:点击查看 题目大意:给出一个长度为偶数的字符串,问将其分割成 k 个子串记为 a[ 1 ] , a[ 2 ] ... a[ k ] ,且满足 a[ i ] == a[ k - i + 1 ] ...

最新文章

  1. shell中数字大小的比较
  2. app专项测试(稳定性测试、安全性测试)
  3. 如何在Spyder中运行spark
  4. php ip访问mysql什么配置_PHP与MYSQL配合完成IP的存取
  5. 云函数连接mysql超时_云函数访问MYSQL数据库出错?
  6. FZU - 2218 Simple String Problem(状压dp)
  7. 多么痛的领悟--写在领英股票被腰斩之后
  8. 深度学习,路在何方?
  9. Div+CSS布局入门教程(四) 页面顶部制作之二
  10. RestExpress response中addHeader 导致stackOverflow
  11. ubuntu 的chmod 和 chown
  12. jlink6.80a烧写序列号(serial number)问题记录
  13. 怎么制作游戏脚本_自动玩游戏,手游脚本究竟是怎么做的?
  14. pgAdmin 3 编译安装
  15. Netch + Connectify 实现代理转全局并共享给其他设备,例如Kindle
  16. windows屏幕放大镜
  17. 通过域名访问文件共享服务器,域名访问共享文件夹
  18. DHTMLXGantt in Flutter DHTMLXGantt
  19. 【程序哥】分析 网易一元夺宝是否有作弊空间,真像媒体所说的吗?
  20. 【C语言】指针终结者-初阶

热门文章

  1. python3抓取图片_通过Python3 爬虫抓取漫画图片
  2. anaconda和python有什么不一样_黄山毛峰的味道为什么会不一样?
  3. 中科大计算机是一流学科吗,安徽2017双一流学科排行榜:中国科技大学第一
  4. tankwar java_TankWar 单机(JAVA版) 版本0.3 画出坦克
  5. suse linux 文件只可读,SUSE LINUX下文件系统变只读的问题解决
  6. 文件共享服务器第二部,第二章-构建Samba文件共享服务器.docx
  7. vector容器中查找某一元素是否存在(牛逼的vector!!!!!!)
  8. html5访问本地资源,HTML5实现一个访问本地文件的实例今
  9. java swing 控件拖动_java swing中实现拖拽功能示例
  10. [数据结构-严蔚敏版]P65离散事件模拟(银行客户的离散事件驱动模拟程序)