luogu P2216 [HAOI2007]理想的正方形
阿新 • • 發佈:2018-11-06
LBA就是強啊...
一開始看這個題的時候還以為一個st表就搞完了
但是交完了T (發現是自己寫跪了 updated on 11.06 3 p.m.)
決定還是練一下單調佇列 畢竟不太好寫
然後這題需要維護兩個單調佇列分別表示最大最小值
然後再開兩級分別維護一行中的最值(x[][])和 上一級單調佇列中的最值 (y[][])
這樣y[][]存的就不是一列的最值 而是最終正方形中的最值
最後最值就是按左上角角標存在y[][] 直接算就行
(也不知道考試能不能想到)
Time cost:60min
Code:
1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 #include<cmath>
5 #include<queue>
6 #include<iostream>
7 #define ms(a,b) memset(a,b,sizeof a)
8 #define rep(i,a,n) for(int i = a;i <= n;i++)
9 #define per(i,n,a) for(int i = n;i >= a;i--)
10 #define inf 2147483647
11 using namespace std;
12 typedef long long ll;
13 typedef double D;
14 #define eps 1e-8
15 ll read() {
16 ll as = 0,fu = 1;
17 char c = getchar();
18 while(c < '0' || c > '9') {
19 if(c == '-') fu = -1;
20 c = getchar();
21 }
22 while(c >= '0' && c <= ' 9') {
23 as = as * 10 + c - '0';
24 c = getchar();
25 }
26 return as * fu;
27 }
28 //head
29 const int N = 1005;
30 int n,m,k;
31 int a[N][N];
32 int head,tail,q[N];
33 int Head,Tail,Q[N];
34 int X[N][N],x[N][N],Y[N][N],y[N][N];
35 int main() {
36 // freopen("in.in","r",stdin);
37 n = read(),m = read(),k = read();
38 // printf("%d %d %d\n",n,m,k);
39 rep(i,1,n) rep(j,1,m) a[i][j] = read();
40 rep(i,1,n) {
41 head = tail = Head = Tail = Q[1] = q[1] = 1;
42 rep(j,2,m) {
43 while(Head <= Tail && a[i][Q[Tail]] <= a[i][j]) Tail--;
44 while(head <= tail && a[i][q[tail]] >= a[i][j]) tail--;
45 Q[++Tail] = q[++tail] = j;
46 while(j-Q[Head] >= k) Head++;
47 while(j-q[head] >= k) head++;
48 if(j >= k) {
49 X[i][j-k+1] = a[i][Q[Head]];
50 x[i][j-k+1] = a[i][q[head]];
51 }
52 }
53 }
54 //x[n][m-k+1]
55 rep(i,1,m-k+1) {
56 Head = Tail = head = tail = q[1] = Q[1] = 1;
57 rep(j,1,n) {
58 while(Head <= Tail && X[Q[Tail]][i] <= X[j][i]) Tail--;
59 while(head <= tail && x[q[tail]][i] >= x[j][i]) tail--;
60 Q[++Tail] = q[++tail] = j;
61 while(j - Q[Head] >= k) Head++;
62 while(j - q[head] >= k) head++;
63 if(j >= k) {
64 Y[j-k+1][i] = X[Q[Head]][i];
65 y[j-k+1][i] = x[q[head]][i];
66 }
67 }
68 }
69 int minn = inf;
70 rep(i,1,n-k+1) rep(j,1,m-k+1) {
71 minn = min(minn,Y[i][j] - y[i][j]);
72 }
73 printf("%d\n",minn);
74 return 0;
75 }
View Code