1. 程式人生 > >luogu P2216 [HAOI2007]理想的正方形

luogu P2216 [HAOI2007]理想的正方形

傳送門

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