CF1208F Bits And Pieces

枚举 \(i\)

从高往低贪心,令当前枚举到了第 \(t\) 位。

如果 \(a_i\) 的第 \(t\) 位为 \(0\),则尝试在 \(i\) 后面找两个位置 \(j,k\) 使得 \(a_j,a_k\) 的第 \(t\) 位都是 \(1\),且不违背前面已经选好的答案。「不违背」的意思是指,前面已经选好的每个要求是 \(1\) 的位,在 \(a_j,a_k\) 上也是 \(1\)

具体的,令前面已经选好的答案为 \(ans\),那么后两个位置 \(j,k\) 需要满足 \(ans+2^t \subseteq a_j, a_k\)

如何判断这样的 \(j,k\) 是否存在?高维前缀和预处理 \(p(x),q(x)\) 表示所有满足 \(y \subseteq x\)\(y\) 中最后和次后的出现位置。那么合法等价于 \(q(x) > i\)

// Problem: 
//     Bits And Pieces
//   
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF1208F
// Memory Limit: 250 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

using namespace std;

const int N = 1e7 + 10, M = 22;

int n, a[N];
int p[N], q[N];

void work(int &x, int &y, int k) {
	if (k >= x) y = x, x = k;
	else if (k >= y) y = k;
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n;
	
	for (int i = 1; i <= n; ++ i ) {
		cin >> a[i];
		work(p[a[i]], q[a[i]], i);
	}
	
	for (int j = 0; j < M; ++ j )
		for (int i = 0; i < 1 << M; ++ i )
			if (i >> j & 1) {
				work(p[i ^ (1 << j)], q[i ^ (1 << j)], p[i]);
				work(p[i ^ (1 << j)], q[i ^ (1 << j)], q[i]);
			}
	
	int ans = 0;
	for (int i = 1; i <= n; ++ i ) {
		int res = 0;
		for (int j = M - 1; ~j; -- j )
			if (!(a[i] >> j & 1)) {
				if (p[res | (1 << j)] > i && q[res | (1 << j)] > i) res |= 1 << j;
			}
		if (i + 2 <= n) ans = max(ans, res | a[i]);
	}
	
	cout << ans;
	
	return 0;
}
posted @ 2025-01-23 15:50  2huk  阅读(14)  评论(0)    收藏  举报
2048 Game
Score
0
Best
0