您的位置:首页 > 其它

[PKU 2823]Sliding Windows(单调队列版)

2009-09-24 14:01 501 查看
【题目大意】:见上篇日志

【题目分析】:

经过对该题的重新分析,得出如下算法。

开一个单调队列,然后记录单调队列中元素对应原序列中的位置以及原序列中的数对应单调队列中的位置,如果不在队列中或改数已过期,那么标记为-1。

然后运用单调队列进行筛选,开始时将前m个元素进行进队。然后从第m+1个元素开始,首先标记第i-m个元素为过期,然后将单调队列中前面的过期的数出队,然后将新的数插入,那么队头就是新的最值。

【代码(我冲进ranklist前10的代码~)】

program PKU_2823;
var
a,q,qlink,link:array[1..1000000] of longint;
n,m,i,front,rear:longint;
begin
assign(input,'a.in');
assign(output,'a.out');
reset(input); rewrite(output);
readln(n,m);
for i:=1 to n do
read(a[i]);
q[1]:=a[1]; link[1]:=1; qlink[1]:=1; front:=1; rear:=1;
for i:=2 to m do
begin
inc(rear);
while (rear>front) and (a[i]<q[rear-1]) do
begin
dec(rear);
link[qlink[rear]]:=-1;
end;
qlink[rear]:=i;
link[i]:=rear;
q[rear]:=a[i];
end;
write(q[front]);
for i:=m+1 to n do
begin
link[i-m]:=-1;
while (link[qlink[front]]=-1) and (front<=rear) do inc(front);
inc(rear);
while (rear>front) and (a[i]<q[rear-1]) do
begin
dec(rear);
link[qlink[rear]]:=-1;
end;
qlink[rear]:=i;
link[i]:=rear;
q[rear]:=a[i];
write(' ',q[front]);
end;
writeln;
q[1]:=a[1]; link[1]:=1; qlink[1]:=1; front:=1; rear:=1;
for i:=2 to m do
begin
inc(rear);
while (rear>front) and (a[i]>q[rear-1]) do
begin
dec(rear);
link[qlink[rear]]:=-1;
end;
qlink[rear]:=i;
link[i]:=rear;
q[rear]:=a[i];
end;
write(q[front]);
for i:=m+1 to n do
begin
link[i-m]:=-1;
while (link[qlink[front]]=-1) and (front<=rear) do inc(front);
inc(rear);
while (rear>front) and (a[i]>q[rear-1]) do
begin
dec(rear);
link[qlink[rear]]:=-1;
end;
qlink[rear]:=i;
link[i]:=rear;
q[rear]:=a[i];
write(' ',q[front]);
end;
writeln;
close(input); close(output);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: