Luogu 2216[HAOI2007]理想的正方形 - 单调队列
Solution
二维单调队列, 这个数组套起来看得我眼瞎。。。
Code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define rd read() 5 #define rep(i,a,b) for(register int i = (a); i <= (b); ++i) 6 #define per(i,a,b) for(register int i = (a); i >= (b); --i) 7 #define Lb lb[i] 8 #define Rb rb[i] 9 #define Ls ls[i] 10 #define Rs rs[i] 11 using namespace std; 12 13 const int N = 1e3 + 100; 14 const int inf = ~0U >> 1; 15 16 int n, m, len, a[N][N]; 17 int qb[N][N], lb[N], rb[N]; 18 int qs[N][N], ls[N], rs[N]; 19 20 int qB[N], LB, RB; 21 int qS[N], LS, RS; 22 23 int ans = inf; 24 25 int read() { 26 int X = 0, p = 1; char c = getchar(); 27 for(; c > '9' || c < '0'; c = getchar()) if(c == '-') p = -1; 28 for(; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0'; 29 return X * p; 30 } 31 32 int main() 33 { 34 n = rd; m = rd; len = rd; 35 rep(i, 1, n) rep(j, 1, m) a[i][j] = rd; 36 rep(i, 1, n) ls[i] = lb[i] = 1; 37 rep(j, 1, m) { 38 rep(i, 1, n) { 39 while(qb[i][Lb] <= j - len && Lb <= Rb) Lb++; 40 while(qs[i][Ls] <= j - len && Ls <= Rs) Ls++; 41 42 while(Lb <= Rb && a[i][qb[i][Rb]] <= a[i][j]) Rb--; 43 while(Ls <= Rs && a[i][qs[i][Rs]] >= a[i][j]) Rs--; 44 qb[i][++Rb] = j; 45 qs[i][++Rs] = j; 46 } 47 LS = LB = 1; 48 RB = RS = 0; 49 if(j >= len) 50 rep(i, 1, n) { 51 while(qB[LB] <= i - len && LB <= RB) LB++; 52 while(qS[LS] <= i - len && LS <= RS) LS++; 53 54 while(LB <= RB && a[qB[RB]][qb[qB[RB]][lb[qB[RB]]]] <= a[i][qb[i][Lb]]) RB--; 55 while(LS <= RS && a[qS[RS]][qs[qS[RS]][ls[qS[RS]]]] >= a[i][qs[i][Ls]]) RS--; 56 qB[++RB] = i; 57 qS[++RS] = i; 58 int hb = qB[LB], hs = qS[LS]; 59 if(i >= len) ans = min(ans, a[hb][qb[hb][lb[hb]]] - a[hs][qs[hs][ls[hs]]]); 60 } 61 } 62 printf("%d\n", ans); 63 }