zoukankan      html  css  js  c++  java
  • 【以前的空间】 单调队列系列

    https://www.vijos.org/p/1580

      这道题可以很简单地写出一个二维循环的解法,就是对于每个节点i,往前扫比这个节点高度大的节点,看能扫到哪,往后扫对这个节点高度大的节点,看能扫到哪。这样对于n≤100,000的数据会爆。于是我们可以想到,如果我们是这样处理:即对于节点i,我们并不是找他能扫到哪,而是节点i是哪个节点的最后或者最左的节点。然后就用到神奇的单调队列:首先对于节点i,将i之前比它高的点j全出队,因为此时j不可能扫过i(a[j]>a[i]),然后j能扫到最右的距离就是i了;然后再将此点入队。  一个小东西就是把n+1点的高度弄完0,这样所有点就都比n+1大了……

    var
     s,q,s2,a:array[0..10]of int64;
     i,j,k,l,r,n:longint;
     ans:int64;
    
    begin
     while not eof do begin
       fillchar(s,sizeof(s),0);
       fillchar(q,sizeof(q),0);
       read(n);
       for i:=1 to n do
         read(a[i]);
       readln;
       l:=1;
       r:=0;
       for i:=1 to n+1 do begin
         while (l<=r) and (a[i]<a[q[r]]) do begin
           s[q[r]]:=i;
           dec(r);
         end;
         inc(r);
         q[r]:=i;
       end;
       l:=1;
       r:=0;
       fillchar(q,sizeof(q),0);
       for i:=n downto 0 do begin
         while (l<=r) and (a[i]<a[q[r]]) do begin
           s2[q[r]]:=i;
           dec(r);
         end;
         inc(r);
         q[r]:=i;
       end;
       ans:=0;
       for i:=1 to n do
         if (s[i]-s2[i]-1)*a[i]>ans then
           ans:=(s[i]-s2[i]-1)*a[i];
       writeln(ans);
     end;
     writeln('0');
     readln;
    end.
    View Code

    vijos 1091

    var
      a,b,c,f,ff,s:array[0..1000000]of longint;
      i,j,k,l,n,m,r:longint;
      flag:boolean;begin
      readln(n,l);
      readln(b[n],a[1]);
      for i:=2 to n do begin
        readln(b[i-1],a[i]);
        dec(l,b[i-1]);
      end;
      b[n]:=l;
      for i:=1 to n do begin
        c[i]:=a[i]-b[i];
        c[i+n]:=c[i];
      end;
      s[0]:=0;
      for i:=1 to n+n do
        s[i]:=s[i-1]+c[i];
      l:=1;
      r:=0;
      flag:=false;
      for i:=1 to n do begin
        while (l<=r) and (s[i]<ff[r]) do dec(r);
        inc(r);
        ff[r]:=s[i];
        f[r]:=i;
      end;
      for i:=n to n+n-1 do begin
        while (f[l]<=i-n) and (l<=r) do inc(l);
        while (l<=r) and (s[i]<ff[r]) do dec(r);
        inc(r);
        ff[r]:=s[i];
        f[r]:=i;
        if s[i-n]<=ff[l] then begin
          flag:=true;
          write(i-n+1,' ');
        end;
      end;
      if flag=false then begin
        writeln(-1);
      end;end.
    View Code

    转载于:https://www.cnblogs.com/Macaulish/p/6492043.html

  • 相关阅读:
    PAT (Advanced Level) Practice 1071 Speech Patterns (25分)
    PAT (Advanced Level) Practice 1070 Mooncake (25分)
    PAT (Advanced Level) Practice 1069 The Black Hole of Numbers (20分)
    PAT (Advanced Level) Practice 1074 Reversing Linked List (25分)
    PAT (Advanced Level) Practice 1073 Scientific Notation (20分)
    第一次冲刺个人总结01
    构建之法阅读笔记01
    人月神话阅读笔记01
    四则运算2
    学习进度条(软件工程概论1-8周)
  • 原文地址:https://www.cnblogs.com/twodog/p/12141153.html
Copyright © 2011-2022 走看看