Deal with each number closest to its two or so larger number.
The trie can then be persisted.
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#defineMAXN 200050#defineINF 1000000007using namespacestd;structnum{intVal,id;} P[MAXN];intN,A[MAXN];intseg_ls[maxn<<2],seg_rs[maxn<<2],val1[maxn<<2],val2[maxn<<2],seg_root,seg_tot=0, L1[MAXN],L2[MAXN],R1[MAXN],R2[MAXN];inttree[maxn* -][2],sum[maxn* -],root[maxn],bitt[ *],ans=0, tot=0;BOOLcmp (num x,num y) {returnX.val>Y.val;}voidget_table () {bitt[0]=1; for(intI=1; i<= -; i++) Bitt[i]=bitt[i-1]*2;}voidBUILD_SEG (int&now,intLeftintRight ) { Now=++seg_tot;val1[now]=0; val2[now]=inf; if(Left==right)return; intMid= (left+right) >>1; Build_seg (Seg_ls[now],left,mid); Build_seg (Seg_rs[now],mid+1, right);}intASK_SEG (intNowintLeftintRightintPosinttype) { if(left==Right ) { if(type==1)returnVal1[now]; Else returnVal2[now]; } intMid= (left+right) >>1; if(type==1) { if(Pos<=mid)returnMax (Val1[now],ask_seg (Seg_ls[now],left,mid,pos,type)); Else returnMax (Val1[now],ask_seg (seg_rs[now],mid+1, Right,pos,type)); } Else { if(Pos<=mid)returnmin (val2[now],ask_seg (seg_ls[now],left,mid,pos,type)); Else returnMin (Val2[now],ask_seg (seg_rs[now],mid+1, Right,pos,type)); }}voidMODIFY_SEG (intNowintLeftintRightintLintRintXinttype) { if((left==l) && (right==r)) {if(type==1) val1[now]=Max (val1[now],x); Elseval2[now]=min (val2[now],x); return; } intMid= (left+right) >>1; if(r<=mid) modify_seg (Seg_ls[now],left,mid,l,r,x,type); Else if(l>=mid+1) Modify_seg (seg_rs[now],mid+1, Right,l,r,x,type); Else{modify_seg (seg_ls[now],left,mid,l,mid,x,type); Modify_seg (Seg_rs[now],mid+1, right,mid+1, R,x,type); }}voidWorkintx) {L1[p[x].id]=ask_seg (Seg_root,1, N,p[x].id,1); if(l1[p[x].id]==0) l2[p[x].id]=0; Else { if(l1[p[x].id]==1) l2[p[x].id]=0; ElseL2[p[x].id]=ask_seg (Seg_root,1, n,l1[p[x].id]-1,1); } R1[p[x].id]=ask_seg (Seg_root,1, N,p[x].id,2); if(R1[p[x].id]==inf) {r1[p[x].id]=n+1; r2[p[x].id]=n+1;} Else { if(r1[p[x].id]==n) r2[p[x].id]=n+1; ElseR2[p[x].id]=ask_seg (Seg_root,1, n,r1[p[x].id]+1,2); if(R2[p[x].id]==inf) r2[p[x].id]=n+1; } modify_seg (Seg_root,1, N,p[x].id,n,p[x].id,1); Modify_seg (Seg_root,1N1, P[x].id,p[x].id,2);}voidInsertintBintLastint&now,intx) { Now=++tot; tree[now][0]=tree[last][0];tree[now][1]=tree[last][1]; Sum[now]=sum[last]+1; if(b==-1)return; inttmp=x&bitt[b];tmp>>=C; Insert (b-1, tree[last][tmp],tree[now][tmp],x);}intAskintBintLastintNowintx) { if(b==-1)return 0; inttmp=x&bitt[b];tmp>>=b; intr=sum[tree[now][tmp^1]]-sum[tree[last][tmp^1]]; if(r>0)returnAsk (B-1, tree[last][tmp^1],tree[now][tmp^1],X) +Bitt[b]; Else returnAsk (B-1, tree[last][tmp],tree[now][tmp],x);}intMain () {get_table (); scanf ("%d",&N); for(intI=1; i<=n;i++) {scanf ("%d",&A[i]); P[i].val=a[i];p [i].id=i; } sort (P+1, p+n+1, CMP); Build_seg (Seg_root,1, N); for(intI=1; i<=n;i++) work (i); for(intI=1; i<=n;i++) Insert ( -, root[i-1],root[i],a[i]); for(intI=1; i<=n;i++) { intL,r; L=l2[i]+1; r=r1[i]-1; Ans=max (Ans,ask ( -, root[l-1],root[r],a[i])); L=l1[i]+1; r=r2[i]-1; Ans=max (Ans,ask ( -, root[l-1],root[r],a[i])); } printf ("%d\n", ans); return 0;}
Bzoj 3166 Alo