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;
}

浙公网安备 33010602011771号