首先不难想到穷举次大数
然后我们只要找到满足这个数是次大数的最大区间即可
显然答案只可能是这两种[LL[i]+1,R[i]-1]和[L[i]+1,RR[i]-1]
L[i]表示这个数ai左侧第一个比它大的数的位置,
LL[i]表示这个数ai左侧第二个比它的的数的位置
R[i],RR[i]同理
然后假如我们能快速求出这两个区间,那剩下来我们就可以交给可持久化trie解决
下面的问题是如何快速求这两个区间
首先L[i],R[i]比较简单,直接维护一个单调降的队列即可
问题就是LL[i],RR[i],这里就只讲LL[i]了
关注到LL[i]一定在L[i]左侧,从L[i]左侧第一个数考虑,如果它比a[i]大,那它就是左边大于a[i]的第二个数
如果小于,那么L[L[i]-1]+1~L[i]-1一定也不会比a[i]大,我们可以直接跳跃到L[L[i]-1],以此类推
这样处理完所有的LL[i],类似于最大子矩形的做法,均摊是O(n)
由此可以解决

  1 var son:array[-1..10000010,0..1] of longint;
  2     h,ll,l,r,rr,q,a:array[-1..50010] of longint;
  3     n,t,x,i,s,ans:longint;
  4 
  5 function max(a,b:longint):longint;
  6   begin
  7     if a>b then exit(a) else exit(b);
  8   end;
  9 
 10 function add(x,p:longint):longint;
 11   var i,q,y:longint;
 12   begin
 13     inc(t);
 14     add:=t;
 15     q:=t;
 16     for i:=30 downto 0 do
 17     begin
 18       y:=x and (1 shl i);
 19       if y>0 then y:=1;
 20       inc(t);
 21       son[q,y]:=t;
 22       son[q,1-y]:=son[p,1-y];
 23       p:=son[p,y];
 24       q:=t;
 25     end;
 26   end;
 27 
 28 function ask(l,r,x:longint):longint;
 29   var i,q,y:longint;
 30   begin
 31     ask:=0;
 32     for i:=30 downto 0 do
 33     begin
 34       y:=x and (1 shl i);
 35       if y>0 then y:=1;
 36       if (son[r,1-y]=-1) or (son[r,1-y]=son[l,1-y]) then
 37       begin
 38         r:=son[r,y];
 39         l:=son[l,y];
 40       end
 41       else begin
 42         ask:=ask+1 shl i;
 43         r:=son[r,1-y];
 44         l:=son[l,1-y];
 45       end;
 46     end;
 47   end;
 48 
 49 function sl(k:longint):longint;
 50   begin
 51     if (a[i]<a[k]) or (k=0) then exit(k)
 52     else exit(sl(l[k]));
 53   end;
 54 
 55 function sr(k:longint):longint;
 56   begin
 57     if (a[i]<a[k]) or (k=n+1) then exit(k)
 58     else exit(sr(r[k]));
 59   end;
 60 
 61 begin
 62   readln(n);
 63   fillchar(son,sizeof(son),255);
 64   h[0]:=1;
 65   t:=1;
 66   x:=1;
 67   for i:=30 downto 0 do
 68   begin
 69     inc(t);
 70     son[x,0]:=t;
 71   end;
 72   for i:=1 to n do
 73   begin
 74     read(a[i]);
 75     h[i]:=add(a[i],h[i-1]);
 76   end;
 77   a[n+1]:=2147483647;
 78   a[0]:=2147483647;
 79   q[1]:=1;
 80   s:=1;
 81   for i:=2 to n do
 82   begin
 83     while (s>0) and (a[i]>a[q[s]]) do dec(s);
 84     l[i]:=q[s];
 85     inc(s);
 86     q[s]:=i;
 87   end;
 88   q[0]:=n+1;
 89   q[1]:=n;
 90   s:=1;
 91   r[n]:=n+1;
 92   for i:=n-1 downto 1 do
 93   begin
 94     while (s>0) and (a[i]>a[q[s]]) do dec(s);
 95     r[i]:=q[s];
 96     inc(s);
 97     q[s]:=i;
 98   end;
 99   ll[1]:=0;
100   for i:=2 to n do
101     if l[i]>0 then ll[i]:=sl(l[i]-1)
102     else ll[i]:=0;
103   rr[n]:=n+1;
104   i:=1;
105   for i:=n-1 downto 1 do
106     if r[i]<=n then rr[i]:=sr(r[i]+1)
107     else rr[i]:=n+1;
108   ans:=0;
109   for i:=1 to n do
110   begin
111     if (l[i]=0) and (r[i]=n+1) then continue;
112     if (l[i]=0) then
113       ans:=max(ans,ask(h[0],h[rr[i]-1],a[i]))
114     else if r[i]=n+1 then
115       ans:=max(ans,ask(h[ll[i]],h[n],a[i]))
116     else begin
117       ans:=max(ans,ask(h[ll[i]],h[r[i]-1],a[i]));
118       ans:=max(ans,ask(h[l[i]],h[rr[i]-1],a[i]));
119     end;
120   end;
121   writeln(ans);
122 end.
View Code

 

posted on 2015-01-09 22:55  acphile  阅读(129)  评论(0编辑  收藏  举报