考える:単調なメンテナンスキュー内のそれぞれの行と列を。
:特定の方法単調メンテナンス待ち行列の各行の最初の値、およびA [] []の各間隔の最大値、のそれぞれ最小存在X- [] []とX [] []です。
次いで、X-は、[] []とX []は[] 1×nの矩形内にそれぞれ最大値と最小値を記憶されています。X- [I] [J ]メモリのI行のJ〜J + N-1角柱最大値。同様に、X [i]は[J]のストレージI最初の行J〜J + N-1角柱最小限。
再度、各列のこれらの値は、2つの配列を維持するために、X-は、[] []と各区間での最大値であるY [] []メンテナンス、X [] []の各セクションでは最小値Y [] []メンテナンス。次いで、Y [i]は[J]格納されたX- [] []最初のiは〜iがn-1 +長方形最大行j列を。同様に、Y [i] [j]は保存されたX [] []最初のiが〜iがN-1 +最小値の長方形の行j列を。
したがって、Y [i]は[J]と同様に、実ストレージ[I〜Iは、N- + 1] [J〜J + N-1] すなわち、最大でI、Jは、左上隅、辺の長さnは広場の最大値。同様に、Y [I]、[J] 、すなわち記憶されたI、Jは、左上の長さNの正方形の最小値。
シミュレーションプロセスは以下の通り:
コード
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 INTのN、M、K、正面、正面、背面、BACK、ANS。 INT [ 1001 ] [ 1001 ]、Q [ 1001 ]、Q [ 1001 ]。 INT X [ 1001 ] [ 1001 ]、X [ 1001 ] [ 1001 ]。 INT Y [ 1001 ] [ 1001 ]、Y [ 1001 ] [ 1001 ]。 INT メイン() { scanf関数(" %D%D%D "、&N、&M、およびK); 以下のための(int型I = 1 ; Iは<= nであり; Iは++ ) のために(int型 iは= 1 ; I <= M; iが++ ) のscanf(" %dの"、および[I] [I])。 以下のために(int型 I = 1 ; Iは<= N; I ++は) { FRONT = BACK =正面=バック= Q [ 1 ] = Q [ 1 ] = 1 。 以下のために(int型 I = 2 ; I <= M; iは++ ) { 一方([I] [I]> = [I] [Q [BACK] && FRONT <= BACK)BACK-- 。 一方、([I] [I] <= [I] [Q [バック] &&フロント<=背面)back-- 。 BACK ++;バック++; Q [BACK] = I; [戻る] Q = I。 一方、(IQ [FRONT]> = K)FRONT ++ 。 一方、(IQ [フロント]> = K)フロント++ 。 もし(I> = K)X [I] [I-K + 1 ] [I] [Q [FRONT]、X [I] [I-K + = 1 ] = [I] [Q [フロント] ; } } のために(int型 I = 1 ; I <= M-K + 1 ; I ++ ) { FRONT = BACK =正面=バック= Q [ 1 ] = Q [1 ] = 1 。 以下のために(int型、I = 2 ; iが<= N; iが++ ) { 一方(X [i]は[I]> = X [Q [BACK] [I] && FRONT <= BACK)BACK-- 。 一方 back--(X [i]は[I] <= xの[Q [バック] [I] &&フロント<=背面)。 BACK ++;バック++; Q [BACK] = I; [戻る] Q = I。 一方、(IQ [FRONT]> = K)FRONT ++ 。 一方、(IQ [フロント]> = K)フロント++ 。 もし(私は> = K)Y [I-K + 1 ] [I] = X [Q [FRONT] [I]、Y [I-K + 1 ] [I] =X [Q [フロント] [I]。 } } ANS = 0x3f3f3f3f 。 以下のために(int型 Iは= 1 ; I <= N-K + 1 ; I ++の) のために(int型 I = 1 ; I <= M-K + 1 ; iが++ ) ANS =分(ANS、Y [I] [I] - Y [ I] [I]); printf(" %d個の\ n " 、ANS)。 リターン 0 ; }