Window_纪中_1326_单调队列
题目大意
给你一个度为N的数组,一个长为K的滑动的窗体从最左移至最右端,你只能见到窗口的K个数,每次窗体向右移动一位,如下表:
你的任务是找出窗口在各位置时的max value,min value.
分析
水法见——水法
还可以用单调队列。
单调队列见——单调队列
但是都要卡时间,pascal的问题
代码
var a:array[0..1000001] of longint; d,v:array[0..1000001] of longint; head,tail:longint; i,j,k:longint; n,m:longint; begin readln(n,m); for i:=1 to n do read(a[i]); head:=1; tail:=1; d[1]:=a[1]; v[1]:=1; for i:=2 to m do begin while (d[tail]>a[i]) and (head<=tail) do tail:=tail-1; tail:=tail+1; d[tail]:=a[i]; v[tail]:=i; end; write(d[1],' '); for i:=m+1 to n do begin while (v[head]<=i-m) and (head<=tail) do head:=head+1; if tail<head then tail:=head; while (d[tail]>a[i]) and (head<=tail) do tail:=tail-1; tail:=tail+1; d[tail]:=a[i]; v[tail]:=i; write(d[head],' '); end; writeln; fillchar(d,sizeof(d),0); fillchar(v,sizeof(v),0); head:=1; tail:=1; d[1]:=a[1]; v[1]:=1; for i:=2 to m do begin while (d[tail]<a[i]) and (head<=tail) do tail:=tail-1; tail:=tail+1; d[tail]:=a[i]; v[tail]:=i; end; write(d[1],' '); for i:=m+1 to n do begin while (v[head]<=i-m) and (head<=tail) do head:=head+1; if tail<head then tail:=head; while (d[tail]<a[i]) and (head<=tail) do tail:=tail-1; tail:=tail+1; d[tail]:=a[i]; v[tail]:=i; write(d[head],' '); end; end.