解决RMQ关键步骤:
单调队列的进队出队:
进队时,将进队的元素为e,从队尾往前扫描,直到找到一个不大于e的元素d,将e放在d之后,舍弃e之后的所有元素;如果没有找到这样一个d,则将e放在队头(此时队列里只有这一个元素)。
出队时,将出队的元素为e,从队头向后扫描,直到找到一个元素f比e后进队,舍弃f之前所有的。
时间复杂度:每个元素最多进队一次,出队一次,摊排分析下来仍然是 O(1)。
代码:
program pro; //单调队列最大值
var
que,pos:array[0..100]of longint;
n,nn,h,t,i,j:longint;
begin
readln(n);
h:=1; t:=0;
for i:=1 to n do
begin
read(nn);
while (t>=h)and(que[t]<nn) do dec(t);
inc(t); que[t]:=nn;
{
pos[t]:=i; //记录在区间的位置
while (pos[h]<l) do inc(h); //如果该队首在区间外则出队
}
write(que[1],' ');
end;
end.