横着用单调队列求最值,再竖着做单调队列即可

 1 #include<bits/stdc++.h>
 2 #define inc(i,l,r) for(int i=l;i<=r;i++)
 3 #define dec(i,l,r) for(int i=l;i>=r;i--)
 4 #define link(x) for(edge *j=h[x];j;j=j->next)
 5 #define mem(a) memset(a,0,sizeof(a))
 6 #define inf 1e9
 7 #define ll long long
 8 #define succ(x) (1<<x)
 9 #define NM 1000+5
10 using namespace std;
11 int read(){
12     int x=0,f=1;char ch=getchar();
13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
14     while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
15     return x*f;
16 }
17 int n,m,p,a[NM][NM],b[NM][NM],c[NM][NM],qt,qh,q[NM],_q[NM],_qh,_qt,s;
18 int main(){
19 //    freopen("data.in","r",stdin);
20     n=read();m=read();p=read();
21     inc(i,1,n)
22     inc(j,1,m)a[i][j]=read();
23     inc(i,1,n){
24         qh=1;qt=0;mem(q);
25         inc(j,1,p){
26             while(qh<=qt&&a[i][q[qt]]<=a[i][j])qt--;
27             q[++qt]=j;
28         }
29         b[i][p]=a[i][q[qh]];
30         inc(j,p+1,m){
31             while(qh<=qt&&q[qh]<j-p+1)qh++;
32             while(qh<=qt&&a[i][q[qt]]<=a[i][j])qt--;
33             q[++qt]=j;
34             b[i][j]=a[i][q[qh]];
35         }
36         qh=1;qt=0;mem(q);
37         inc(j,1,p){
38             while(qh<=qt&&a[i][q[qt]]>=a[i][j])qt--;
39             q[++qt]=j;
40         }
41         c[i][p]=a[i][q[qh]];
42         inc(j,p+1,m){
43             while(qh<=qt&&q[qh]<j-p+1)qh++;
44             while(qh<=qt&&a[i][q[qt]]>=a[i][j])qt--;
45             q[++qt]=j;
46             c[i][j]=a[i][q[qh]];
47         }
48     }
49 /*    inc(j,1,m)printf("%d ",b[i][j]);printf("\n");}
50     inc(i,1,n){
51     inc(j,1,m)printf("%d ",c[i][j]);printf("\n");}*/
52     s=inf;
53     inc(j,p,m){
54         _qh=qh=1;_qt=qt=0;mem(q);mem(_q);
55         inc(i,1,p){
56             while(qh<=qt&&b[q[qt]][j]<=b[i][j])qt--;
57             q[++qt]=i;
58             while(_qh<=_qt&&c[_q[_qt]][j]>=c[i][j])_qt--;
59             _q[++_qt]=i;
60         }
61         s=min(s,b[q[qh]][j]-c[_q[_qh]][j]);
62 //        printf("%d ",s);
63         inc(i,p+1,n){
64             while(qh<=qt&&q[qh]<i-p+1)qh++;
65             while(qh<=qt&&b[q[qt]][j]<=b[i][j])qt--;
66             q[++qt]=i;
67             while(_qh<=_qt&&_q[_qh]<i-p+1)_qh++;
68             while(_qh<=_qt&&c[_q[_qt]][j]>=c[i][j])_qt--;
69             _q[++_qt]=i;s=min(s,b[q[qh]][j]-c[_q[_qh]][j]);
70 //            printf("%d ",b[q[qh]][j]-c[_q[_qh]][j]);
71         }
72 //        printf("\n");
73     }
74     printf("%d\n",s);
75     return 0;
76 }
View Code

 

posted on 2016-01-15 21:00  onlyRP  阅读(143)  评论(0编辑  收藏  举报