题目链接
https://codeforces.com/contest/1208/problem/F
题解
发现自己并不会,orz hyw tql.
考虑枚举 \(i\),那么显然对每个 \(x\),有用的信息只有“最大的 \(j\) 使得存在 \(k\) 满足 \(a_j\&a_k=x\)”. 显然我们可以把这个条件放宽到“\(x\subset a_j\&a_k\)”.
假设上面说的这个东西叫 \(f_x\),那么 \(f_x\) 就等于所有 \(x\subset a_i\) 的 \(i\) 中第二大的。显然可以 FWT.
然后就可以枚举 \(i\) 了,从高到低位贪心。贪心的过程中每次就要求“对某个 \(y\),是否存在 \(k\gt j\gt i,(a_j\&a_k)\subset y\)”,即 \(f_y\gt i\).
时间复杂度 \(O((n+W)\log W)\),\(W\) 为值域。
代码
#include<bits/stdc++.h>
#define llong long long
#define mkpr make_pair
#define x first
#define y second
#define iter iterator
#define riter reverse_iterator
#define y1 Lorem_ipsum_
#define tm dolor_sit_amet_
#define pii pair<int,int>
using namespace std;
inline int read()
{
int x = 0,f = 1; char ch = getchar();
for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}
for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}
return x*f;
}
const int mxN = 1e6;
const int mxA = 1<<21;
const int lgA = 21;
int n;
int a[mxN+3];
pii f[mxA+3];
void updmax(pii &x,int y) {if(y==x.x||y==x.y) return; if(y>x.x) {x.y = x.x,x.x = y;} else if(y>x.y) {x.y = y;}}
int main()
{
n = read(); for(int i=1; i<=n; i++) a[i] = read();
for(int i=1; i<=n; i++) {updmax(f[a[i]],i);}
for(int j=0; j<lgA; j++)
{
for(int i=0; i<(1<<lgA); i++) if(i&(1<<j))
{
updmax(f[i^(1<<j)],f[i].x);
updmax(f[i^(1<<j)],f[i].y);
}
}
int ans = 0;
for(int i=n-2; i>=1; i--)
{
int cur = 0;
for(int j=lgA-1; j>=0; j--)
{
if(a[i]&(1<<j)) {continue;}
if(f[cur|(1<<j)].y>i) {cur |= (1<<j);}
}
ans = max(ans,cur|a[i]);
}
printf("%d\n",ans);
return 0;
}