左右两边的比i大的最近的两个值。然后可持久化字典树即可。
#include<bits/stdc++.h>
using namespace std;
int maxn=0,n,root[1600000],a[50010],cnt=0,l[1600000],r[1600000],p1[50010][25],p2[50010][25],sum[1600000],ans=0,pans=0,l1[50010],r1[50010],l2[50010],r2[50010];
void add(int &rt,int pre,int val,int id)
{
if(!rt)rt=++cnt;
sum[rt]=sum[pre]+1;
if(id<0)return;
if(val&(1<<id))
{
l[rt]=l[pre];
add(r[rt],r[pre],val,id-1);
}
else
{
r[rt]=r[pre];
add(l[rt],l[pre],val,id-1);
}
}
void work(int L,int R,int val,int id)
{
if(id<0)return;
if((1<<id)&val)
{
if(sum[l[R]]-sum[l[L]])
{
pans|=(1<<id);
work(l[L],l[R],val,id-1);
}
else work(r[L],r[R],val,id-1);
}
else
{
if(sum[r[R]]-sum[r[L]])
{
pans|=(1<<id);
work(r[L],r[R],val,id-1);
}
else work(l[L],l[R],val,id-1);
}
}
int main()
{
//freopen("xf.in","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
maxn=max(maxn,a[i]);
p1[i][0]=a[i];
p2[i][0]=a[i];
add(root[i],root[i-1],a[i],29);
}
int gl=log2(n)+2;
for(int i=1;i<=gl;i++)
{
for(int j=1;j<=n;j++)
{
p1[j][i]=max(p1[j][i-1],p1[max(1,j-(1<<(i-1)))][i-1]);
p2[j][i]=max(p2[j][i-1],p2[min(n,j+(1<<(i-1)))][i-1]);
}
}
for(int i=1;i<=n;i++)
{
int w=i-1;
if(i!=1&&p1[w][gl]>a[i])
{
for(int j=gl;j>=0;j--)
{
if(p1[w][j]<=a[i])
{
w-=(1<<j);
}
}
l1[i]=w;
if(w!=1&&p1[w-1][gl]>a[i])
{
w=w-1;
for(int j=gl;j>=0;j--)
{
if(p1[w][j]<=a[i])
{
w-=(1<<j);
}
}
l2[i]=w;
}
}
w=i+1;
if(i!=n&&p2[w][gl]>a[i])
{
for(int j=gl;j>=0;j--)
{
if(p2[w][j]<=a[i])
{
w+=(1<<j);
}
}
r1[i]=min(w,n);
if(w!=n&&p2[w+1][gl]>a[i])
{
w=w+1;
for(int j=gl;j>=0;j--)
{
if(p2[w][j]<=a[i])
{
w+=(1<<j);
if(w>n)break;
}
}
r2[i]=min(n,w);
}
}
}
for(int i=1;i<=n;i++)
{
if(a[i]==maxn)continue;
pans=0;
if(l1[i])
{
int ll=0,rr=n;
if(r1[i])rr=r1[i]-1;
if(l2[i])ll=l2[i];
work(root[ll],root[rr],a[i],29);
}
ans=max(ans,pans);
pans=0;
if(r1[i])
{
int ll=0,rr=n;
if(r2[i])rr=r2[i]-1;
if(l1[i])ll=l1[i];
work(root[ll],root[rr],a[i],29);
}
ans=max(ans,pans);
}
printf("%d\n",ans);
return 0;
}