题目链接

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