这道题可以很简单地写出一个二维循环的解法,就是对于每个节点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.