zoukankan      html  css  js  c++  java
  • bzoj3166

    首先不难想到穷举次大数
    然后我们只要找到满足这个数是次大数的最大区间即可
    显然答案只可能是这两种[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
  • 相关阅读:
    【转】JS模块化工具requirejs教程(二):基本知识
    【转】JS模块化工具requirejs教程(一):初识requirejs
    【转】批处理命令 For循环命令详解!
    【转】NodeJS教程--基于ExpressJS框架的文件上传
    【转】WebSocket 是什么原理?为什么可以实现持久连接?
    网页工具地址
    【转】DataURL在Web浏览器中的兼容性总结
    侯捷STL学习(一)--顺序容器测试
    strstr-strcat实现
    算法设计与分析
  • 原文地址:https://www.cnblogs.com/phile/p/4473034.html
Copyright © 2011-2022 走看看