bzoj 1047 单调队列
首先将每一列压成一行,ans[i,j]代表[i,j]位及以上共n位的最大值,这个可以每一列用单调队列处理,然后对于每一行,类似于上述的处理,这样就可以得出以[i,j]为右下角的边长为n的矩阵的最大值。然后将所有值取相反数,再求一遍最大值,再取相反数,这样就可以得出最小值,然后扫一遍合法的点更新答案。
/************************************************************** Problem: 1047 User: BLADEVIL Language: Pascal Result: Accepted Time:4192 ms Memory:24184 kb ****************************************************************/ //By BLADEVIL var a, b, n :longint; map :array[0..1010,0..1010] of longint; ans :array[0..1010,0..1010,0..2] of longint; que :array[-1..200] of longint; max, min :array[0..1010,0..1010] of longint; print :longint; procedure init; var i, j :longint; begin read(a,b,n); for i:=1 to a do for j:=1 to b do read(map[i,j]); end; procedure insert(x:longint); begin if que[0]=que[-1] then begin inc(que[0]); que[que[0]]:=x; end else begin while (que[0]>que[-1]) and (que[que[0]]<x) do dec(que[0]); inc(que[0]); que[que[0]]:=x; end; end; procedure delete(x:longint); begin if x=que[que[-1]+1] then inc(que[-1]); end; procedure make(x:longint); var i, j, k :longint; begin for j:=1 to b do begin fillchar(que,sizeof(que),0); for i:=1 to a do begin insert(map[i,j]); if i>n then delete(map[i-n,j]); ans[i,j,x]:=que[que[-1]+1]; end; end; for i:=1 to a do begin fillchar(que,sizeof(que),0); for j:=1 to b do begin insert(ans[i,j,x]); if j>n then delete(ans[i,j-n,x]); ans[i,j,x xor 1]:=que[que[-1]+1]; end; end; end; procedure main; var i, j :longint; begin make(0); for i:=1 to a do for j:=1 to b do max[i,j]:=ans[i,j,1]; fillchar(ans,sizeof(ans),0); for i:=1 to a do for j:=1 to b do map[i,j]:=-map[i,j]; make(0); for i:=1 to a do for j:=1 to b do min[i,j]:=-ans[i,j,1]; print:=maxlongint; for i:=n to a do for j:=n to b do if max[i,j]-min[i,j]<print then print:=max[i,j]-min[i,j]; writeln(print); end; begin init; main; end.