先对序列建一个可持久化trie。
然后从大到小将元素插到线段树对应位置。
每次插入前求以该元素为此小值的最大答案
(求该元素在线段树中前驱的前驱+1和后继的后继-1,中间的部分与该元素的最大异或和就是答案)
最大异或和从可持久化trie上查询。
#include <bits/stdc++.h>
using namespace std;
#define N 51000
#define M 11000000
#define ls l,mid,now<<1
#define rs mid+1,r,now<<1|1
int n,ans;
int a[N],pos[N];
int cmp(int x,int y)
{return a[x]>a[y];}
struct trie
{
int cnt;
int ch[M][2],num[M],root[N];
void insert(int &now,int pre,int v,int deep)
{
num[now=++cnt]=num[pre]+1;
if(deep<0)return;
ch[now][0]=ch[pre][0];
ch[now][1]=ch[pre][1];
if(v>>deep&1)insert(ch[now][1],ch[pre][1],v,deep-1);
else insert(ch[now][0],ch[pre][0],v,deep-1);
}
int query(int now,int pre,int v,int deep)
{
if(deep<0)return 0;
int t=v>>deep&1;
if(num[ch[now][t^1]]-num[ch[pre][t^1]])
return (1<<deep)+query(ch[now][t^1],ch[pre][t^1],v,deep-1);
else return query(ch[now][t],ch[pre][t],v,deep-1);
}
}tr1;
struct seg_tree
{
int tr[N<<2],st[110],lp[110],rp[110],top;
void insert(int l,int r,int now,int pos)
{
tr[now]++;
if(l==r)return;
int mid=(l+r)>>1;
if(mid>=pos)insert(ls,pos);
else insert(rs,pos);
}
void insert(int x){insert(0,n+1,1,x);}
void get(int l,int r,int now,int lq,int rq)
{
if(lq<=l&&r<=rq)
{
st[++top]=now;lp[top]=l;rp[top]=r;
return;
}
int mid=(l+r)>>1;
if(mid>=lq)get(ls,lq,rq);
if(mid<rq) get(rs,lq,rq);
}
int findl(int l,int r,int now)
{
if(l==r)return l;
int mid=(l+r)>>1;
if(tr[now<<1])return findl(ls);
else return findl(rs);
}
int findl(int lq,int rq)
{
top=0;get(0,n+1,1,lq,rq);
for(int i=1;i<=top;i++)
if(tr[st[i]])
return findl(lp[i],rp[i],st[i]);
}
int findr(int l,int r,int now)
{
if(l==r)return l;
int mid=(l+r)>>1;
if(tr[now<<1|1])return findr(rs);
else return findr(ls);
}
int findr(int lq,int rq)
{
top=0;get(0,n+1,1,lq,rq);
for(int i=top;i>=1;i--)
if(tr[st[i]])
return findr(lp[i],rp[i],st[i]);
}
}tr2;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
tr1.insert(tr1.root[i],tr1.root[i-1],a[i],30);
pos[i]=i;
}
sort(pos+1,pos+1+n,cmp);
tr2.insert(0);tr2.insert(n+1);
for(int i=1;i<=n;i++)
{
int t=pos[i];
int l1=tr2.findr(0,t-1),r1=tr2.findl(t+1,n+1),l2=0,r2=n+1;
if(l1==0&&r1==n+1)
{tr2.insert(t);continue;}
if(l1!=0)l2=tr2.findr(0,l1-1);
if(r1!=n+1)r2=tr2.findl(r1+1,n+1);
ans=max(ans,tr1.query(tr1.root[r2-1],tr1.root[l2],a[t],30));
tr2.insert(t);
}
printf("%d\n",ans);
return 0;
}