Codeforces 1208F Bits And Pieces
2024-10-21 11:59:38
题目描述
You are given an array a of n integers.
You need to find the maximum value of ai|(aj&ak) over all triplets (i,j,k) such that i<j<k.
大意
给你一个包含n个整数的序列a
你要在所有满足i<j<k的三元组中找到最大的ai|aj&ak
3<=n<=106
0<=a[i]<=2*106
题解
一,位运算
|指的是二进制后的按位或
如 2|5=7,7|9=15
&指的是二进制后的按位且
如 3&2=2,13&10=8
二、题目
说完了简单的位运算,我们正式进入主题
“按位或”有个特点,就是如果一个数当前位置上是1,则结果当前位置上也一定是1
看上去好废话啊
这样的话,我们就可以枚举更方便确定的a[i]
我们不妨定义a[j]&a[k]的值叫q
那么q一定是a[j]和a[k]的子集(数字的子集是转化为二进制后,每一位都小于等于原数字的数,而不是集合)
因此,我们就可以遍历这些数字的子集,要用dfs执行
当然,别忘了高位优先 !
三、dfs深搜
这部分的深搜很像状压DP,我们只需要找出现了两次的子集即可,同时我们还要避免同一个数的子集算了两次
如110的子集010和100的下一个子集都是000
用vis数组记录即可
四、代码
#include<iostream>
using namespace std;
int sum[2000010],a[1000010],vis[2000010],n,ans;
void h(int x,int y){
if(sum[x]>1||vis[x]==y) return ;
++sum[x];
vis[x]=y;
for(int i=0;(1<<i-1)<x;i++)
if(x&(1<<i)) h(x^(1<<i),y);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
h(a[n],n);
h(a[n-1],n-1);
for(int i=n-2;i>=1;i--){
int k=0;
for(int j=20;j>=0;j--){
if(!(a[i]&(1<<j))&&sum[k^(1<<j)]>1) k^=(1<<j);
}
ans=max(ans,a[i]|k);
h(a[i],i);
}
printf("%d",ans);
return 0;
}
最新文章
- Java-计划存储
- PhotoShop常用快捷键
- mybatis动态SQL - like
- 更新包地址安装新版node.js
- shell 判断字符串是否为数字
- 微信小程序之----audio音频播放
- python实战第一天-环境的安装
- C# 控件的缩写
- Angular4.x通过路由守卫进行路由重定向,实现根据条件跳转到相应的页面
- 指针超强汇总(谨记优先级:() >; [] >; *)
- Windows下SVN服务器搭建和基本操作(服务端、客户端)
- .NET方法无限传参数技术
- linux把文件压缩成.tar.gz的命令
- Python编程基础[条件语句if 循环语句 for,while](二)
- Kafka命令操作
- tst
- (转)python3之模块io使用流的核心工具
- SharePoint Online 创建文档库
- Zookeeper系统设计的优点
- java 自定义泛型