传送门
文章目录
- 题意:
- 思路:
题意:
n≤1e6,ai≤2e6n\le1e6,a_i\le2e6n≤1e6,ai≤2e6
思路:
由于(aj&ak)(a_j \And a_k)(aj&ak)打的括号,所以应该放在一起考虑,现在我们可以枚举aia_iai,由于是或操作,所以我们肯定是从高位到低位贪心的选,如果当前iii右边有两个数他们这一位都是111,那么答案这一位一定是111。当然如果aia_iai的这一位也是111就不需要考虑这一位了,直接跳过就好。现在问题转换成了如何快速判断当前这位右边是否存在一个超集它这一位是111。
很容易想到用sosdpsosdpsosdp来预处理出所有超集,这样处理出来的是整个数组的,但是怎么判断当前位右边是否有至少两个呢?我们可以记一个超集的最右边的两个位置,当i≥i\gei≥当前第二大的位置的时候这一位就不能要。
实现起来就很简单辣。
// Problem: F. Bits And Pieces
// Contest: Codeforces - Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)
// URL: https://codeforces.com/contest/1208/problem/F
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=2000005,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;int n;
int a[N];
PII pos[N];void add(int val,int id) {//if(id==-1) return;if(pos[val].X==-1) {pos[val].X=id;return;} else if(pos[val].Y==-1) {if(pos[val].X==id) return;pos[val].Y=id;if(id>pos[val].X) pos[val].Y=pos[val].X,pos[val].X=id;} else {if(id==pos[val].X||id==pos[val].Y) return;if(id>pos[val].X) pos[val].Y=pos[val].X,pos[val].X=id;else if(id>pos[val].Y) pos[val].Y=id; }
}int main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);scanf("%d",&n);memset(pos,-1,sizeof(pos));for(int i=1;i<=n;i++) scanf("%d",&a[i]),add(a[i],i);for(int i=0;i<21;i++) for(int j=0;j<N;j++) {if(j>>i&1) {add(j^(1<<i),pos[j].X);add(j^(1<<i),pos[j].Y);}}int ans=0;for(int i=1;i<=n-2;i++) {int now=0;for(int j=20;j>=0;j--) {if(a[i]>>j&1) continue;now+=1<<j;if(now>=N||pos[now].Y<=i||pos[now].Y==-1) now-=1<<j; }ans=max(ans,a[i]|now);}printf("%d\n",ans);return 0;
}
/**/