[luoguP2216] [HAOI2007]理想的正方形(二维单调队列)
Posted 蒟蒻zht的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luoguP2216] [HAOI2007]理想的正方形(二维单调队列)相关的知识,希望对你有一定的参考价值。
1.先弄个单调队列求出每一行的区间为n的最大值最小值。
2.然后再搞个单调队列求1所求出的结果的区间为n的最大值最小值
3.最后扫一遍就行
懒得画图,自己体会吧。
——代码
1 #include <cstdio> 2 #include <iostream> 3 4 using namespace std; 5 6 const int MAXN = 1001; 7 int a, b, n, h, t; 8 long long c[MAXN][MAXN], q[MAXN], max1[MAXN][MAXN], min1[MAXN][MAXN], max2[MAXN][MAXN], min2[MAXN][MAXN], ans = 1000000001; 9 10 inline void work1(int k) 11 { 12 int i, j; 13 h = 1, t = 0; 14 for(i = 1; i <= b; i++) 15 { 16 while(h <= t && c[k][q[t]] > c[k][i]) t--; 17 q[++t] = i; 18 while(h <= t && q[h] <= i - n) h++; 19 min1[k][i] = c[k][q[h]]; 20 } 21 h = 1; t = 0; 22 for(i = 1; i <= b; i++) 23 { 24 while(h <= t && c[k][q[t]] < c[k][i]) t--; 25 q[++t] = i; 26 while(h <= t && q[h] <= i - n) h++; 27 max1[k][i] = c[k][q[h]]; 28 } 29 } 30 31 inline void work2(int k) 32 { 33 int i, j; 34 h = 1, t = 0; 35 for(i = 1; i <= a; i++) 36 { 37 while(h <= t && min1[q[t]][k] > min1[i][k]) t--; 38 q[++t] = i; 39 while(h <= t && q[h] <= i - n) h++; 40 min2[i][k] = min1[q[h]][k]; 41 } 42 h = 1; t = 0; 43 for(i = 1; i <= a; i++) 44 { 45 while(h <= t && max1[q[t]][k] < max1[i][k]) t--; 46 q[++t] = i; 47 while(h <= t && q[h] <= i - n) h++; 48 max2[i][k] = max1[q[h]][k]; 49 } 50 } 51 52 int main() 53 { 54 int i, j; 55 scanf("%d %d %d", &a, &b, &n); 56 for(i = 1; i <= a; i++) 57 for(j = 1; j <= b; j++) 58 scanf("%lld", &c[i][j]); 59 for(i = 1; i <= a; i++) work1(i); 60 for(i = 1; i <= b; i++) work2(i); 61 for(i = n; i <= a; i++) 62 for(j = n; j <= b; j++) 63 ans = min(ans, max2[i][j] - min2[i][j]); 64 printf("%lld", ans); 65 return 0; 66 }
以上是关于[luoguP2216] [HAOI2007]理想的正方形(二维单调队列)的主要内容,如果未能解决你的问题,请参考以下文章