每个宝石找出他能产生贡献即他是最大值的区间,【左边的第二个比他大的+1~右边的第二个比他大的-1】
然后写个可持久化trie每个宝石算一下最大值就好了
找左右第二个比他大的可以按宝石的权值从大到小插入,在线段树上二分
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define inf 1e9
using namespace std;
void up(int &x,int y){if(x<y)x=y;}
void down(int &x,int y){if(x>y)x=y;}
const int maxn = 51000;
struct node
{
int c,i;
}s[maxn];
bool cmp(node x,node y){return x.c>y.c;}
int n,a[maxn],le[maxn],ri[maxn];
int tr[maxn<<3];
void ins(int x,int l,int r,int loc)
{
if(l==r) {tr[x]=1; return ;}
int mid=(l+r)>>1,lc=x<<1,rc=lc|1;
if(loc<=mid) ins(lc,l,mid,loc);
else ins(rc,mid+1,r,loc);
tr[x]++;
}
int q1(int x,int l,int r,int loc,int &k)
{
if(l==r) { k--; return l; }
int mid=(l+r)>>1,lc=x<<1,rc=lc|1;
if(loc<=mid&&loc>=l) return q1(lc,l,mid,loc,k);
else
{
int re;
if(tr[rc]) re=q1(rc,mid+1,r,loc,k);
if(!k) return re;
else
{
if(tr[lc]>=k) return q1(lc,l,mid,loc,k);
else {k-=tr[lc]; return re;}
}
}
}
int q2(int x,int l,int r,int loc,int &k)
{
if(l==r) { k--; return l; }
int mid=(l+r)>>1,lc=x<<1,rc=lc|1;
if(loc>mid&&loc<=r) return q2(rc,mid+1,r,loc,k);
else
{
int re;
if(tr[lc]) re=q2(lc,l,mid,loc,k);
if(!k) return re;
else
{
if(tr[rc]>=k) return q2(rc,mid+1,r,loc,k);
else {k-=tr[rc]; return re;}
}
}
}
struct trie
{
int lc,rc,c;
}te[maxn*80]; int num;
int bit[34];
int root[maxn];
void newte(int &x)
{
x=++num;
te[x].lc=te[x].rc=te[x].c=0;
}
void upd(int &x,int now,int loc)
{
if(!x) newte(x);
te[x].c++;
if(now==31) return ;
if(loc&bit[now]) upd(te[x].rc,now+1,loc);
else upd(te[x].lc,now+1,loc);
}
void merge(int &x,int la)
{
if(!x) { x=la; return ; }
if(!la) return ;
te[x].c+=te[la].c;
merge(te[x].lc,te[la].lc);
merge(te[x].rc,te[la].rc);
}
int query(trie x1,trie x2,int k,int now,int r)
{
if(now==31) return r;
if(k&bit[now])
{
if(te[x2.lc].c-te[x1.lc].c) {r|=bit[now]; return query(te[x1.lc],te[x2.lc],k,now+1,r); }
else return query(te[x1.rc],te[x2.rc],k,now+1,r);
}
else
{
if(te[x2.rc].c-te[x1.rc].c) {r|=bit[now]; return query(te[x1.rc],te[x2.rc],k,now+1,r); }
else return query(te[x1.lc],te[x2.lc],k,now+1,r);
}
}
int main()
{
num=0; te[0].lc=te[0].rc=te[0].c=0;
for(int i=0;i<=30;i++) bit[i]=1<<30-i;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
s[i].i=i; s[i].c=a[i];
}
sort(s+1,s+n+1,cmp);
for(int i=1;i<=n;i++)
{
ins(1,1,n,s[i].i);
int ki=3;
le[s[i].i]=q1(1,1,n,s[i].i,ki);
ki=3;
ri[s[i].i]=q2(1,1,n,s[i].i,ki);
}
for(int i=1;i<=n;i++)
{
upd(root[i],0,a[i]);
merge(root[i],root[i-1]);
}
int ret=0;
for(int i=1;i<=n;i++)
{
int l,r;
l=le[i]+1,r=ri[i]-1;
if(le[i]==i) l=1;
if(ri[i]==i) r=n;
if(i==s[1].i) continue;
up(ret,query(te[root[l-1]],te[root[r]],a[i],0,0));
}
printf("%d\n",ret);
return 0;
}