See the difference or maximum is easy to think of the trie tree, as for the interval of different or maximum, can be persisted can be done.
As for meeting the second big value ...
Reverse sort weights, then insert their coordinates into set, and after each lower_bound, look for the front and rear drive.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <set
> #define MAXN 50010 #define INF 0x3fffffff using namespace std;
set<int>s;
int n,ch[maxn*35][2],rt[maxn],bin[35],tot,size[maxn*35];
struct node{int x,id; BOOL operator< (const node& y) Const{return x>y.x;}
A[MAXN];
int insert (int x,int val) {int root=++tot;int y=root;
for (int c,i=30;i>=0;i--) {c= (val>>i) &1;
CH[Y][!C]=CH[X][!C];
Y=ch[y][c]=++tot;
X=CH[X][C];
size[y]=size[x]+1;
return root;
int query (int l,int r,int val) {int ans=0;
for (int c,i=30;i>=0;i--) {c= (val>>i) &1;
if (Size[ch[r][!c]]-size[ch[l][!c]]) r=ch[r][!c],l=ch[l][!c],ans=ans<<1|1;
else l=ch[l][c],r=ch[r][c],ans=ans<<1;
return ans;
int main () {scanf ("%d", &n);
for (int i=1;i<=n;i++) {scanf ("%d", &a[i].x); a[i].id=i;
Rt[i]=insert (rt[i-1],a[i].x);
}sort (A+1,a+1+n); S.insert ( -1), S.insert (INF); S.insert (a[1).ID);
S.insert (inf+1), S.insert (-2);
Set <int>::iterator l,r;
int ans=0,x,y;
for (int i=2;i<=n;i++) {l=r=s.lower_bound (a[i].id);
l--;l--;r++;
X=*l+1,y=*r-1;
X=max (1,x), Y=min (y,n);
Ans=max (Ans,query (rt[x-1],rt[y],a[i].x));
S.insert (a[i].id);
printf ("%d", ans);
return 0; }