Codeforces F. Bits And Pieces(位运算)

传送门.

位运算的比较基本的题。

考虑枚举i,然后二进制位从大到小考虑, 对于第w位,如果a[i][w]=1,那么对jk并没有什么限制。

如果a[i][w]=0,那么我们希望(a[j] and a[k])[w]=1,结合前面的限制,就是给定x,问有没有xa[j] and a[k](i<j<k)

那么这应该是做一个高维后缀max和次max就能解决的事。

Code:


复制#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x; i <= y; i ++)
#define ff(i, x, y) for(int i = x; i <  y; i ++)
#define fd(i, x, y) for(int i = x; i >= y; i --)
#define pp printf
#define ll long long
using namespace std;
 
const int N = 1e6 + 10;
 
int n, a[N];
	
const int M = 1 << 21;
 
int f[M], g[M];
 
void add(int x, int i) {
	if(x > f[i]) {
		g[i] = f[i];
		f[i] = x;
	} else 
	if(x > g[i]){
		g[i] = x;
	}
}
 
const int inf = 1e9;
 
int main() {
	scanf("%d", &n);
	fo(i, 1, n) {
		scanf("%d", &a[i]);
		add(i, a[i]);
	}
	fo(i, 0, 20) {
		ff(j, 0, 1 << 21) {
			if(!(j >> i & 1))	{
				add(f[j + (1 << i)], j);
				add(g[j + (1 << i)], j);
			}
		}
	}
	ff(j, 0, 1 << 21) {
		if(f[j] != g[j]) {
			f[j] = g[j];
		} else {
			f[j] = 0;
		}
	}
	int ans = 0;
	fo(i, 1, n - 2) {
		int x = 0;
		fd(j, 20, 0) {
			if(!(a[i] >> j & 1)) {
				x += 1 << j;
				if(g[x] <= i) {
					x -= 1 << j;
				}
			}
		}
		ans = max(ans, x | a[i]);
	}
	pp("%d", ans);
}
posted @   Cold_Chair  阅读(247)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示