题目链接
https://codeforces.com/contest/1208/problem/F
题解
发现自己并不会,orz hyw tql.
考虑枚举 (i),那么显然对每个 (x),有用的信息只有“最大的 (j) 使得存在 (k) 满足 (a_j&a_k=x)”. 显然我们可以把这个条件放宽到“(xsubset a_j&a_k)”.
假设上面说的这个东西叫 (f_x),那么 (f_x) 就等于所有 (xsubset a_i) 的 (i) 中第二大的。显然可以 FWT.
然后就可以枚举 (i) 了,从高到低位贪心。贪心的过程中每次就要求“对某个 (y),是否存在 (kgt jgt i,(a_j&a_k)subset y)”,即 (f_ygt 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
",ans);
return 0;
}