码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ1047][HAOI2007]理想的正方形 二维单调队列

时间:2017-10-10 21:49:10      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:online   大小   www   san   题目   正方形   string   span   mil   

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1047

我们对每矩阵的一列维护一个大小为$n$的单调队列,队中元素为矩阵中元素。然后扫描每一行,再次维护一个大小为$n$的单调队列,队中元素为当前列的队列中取出的最值。$O(n^2)$扫过去就可以了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int INF=1<<30;
 6 int inline readint(){
 7     int Num;char ch;
 8     while((ch=getchar())<0||ch>9);Num=ch-0;
 9     while((ch=getchar())>=0&&ch<=9) Num=Num*10+ch-0;
10     return Num;
11 }
12 int A,B,N;
13 int M[1010][1010];
14 int qmn1[1010][1010],qmn2[1010][1010],hmn[1010],tmn[1010];
15 int qmx1[1010][1010],qmx2[1010][1010],hmx[1010],tmx[1010];
16 int Qmn1[1010],Qmn2[1010],Hmn,Tmn;
17 int Qmx1[1010],Qmx2[1010],Hmx,Tmx;
18 int main(){
19     A=readint();
20     B=readint();
21     N=readint();
22     for(int i=1;i<=A;i++)
23         for(int j=1;j<=B;j++)
24             M[i][j]=readint();
25     for(int i=1;i<=B;i++){
26         hmx[i]=hmn[i]=1;
27         tmx[i]=tmn[i]=0;
28         for(int j=1;j<N;j++){
29             while(hmx[i]<=tmx[i]&&qmx1[i][tmx[i]]<=M[j][i]) tmx[i]--;
30             qmx1[i][++tmx[i]]=M[j][i];
31             qmx2[i][tmx[i]]=j;
32             while(hmn[i]<=tmn[i]&&qmn1[i][tmn[i]]>=M[j][i]) tmn[i]--;
33             qmn1[i][++tmn[i]]=M[j][i];
34             qmn2[i][tmn[i]]=j;
35         }
36     }
37     int ans=INF;
38     for(int i=N;i<=A;i++){
39         for(int j=1;j<=B;j++){
40             while(hmx[j]<=tmx[j]&&qmx2[j][hmx[j]]+N<=i) hmx[j]++;
41             while(hmx[j]<=tmx[j]&&qmx1[j][tmx[j]]<=M[i][j]) tmx[j]--;
42             qmx1[j][++tmx[j]]=M[i][j];
43             qmx2[j][tmx[j]]=i;
44             while(hmn[j]<=tmn[j]&&qmn2[j][hmn[j]]+N<=i) hmn[j]++;
45             while(hmn[j]<=tmn[j]&&qmn1[j][tmn[j]]>=M[i][j]) tmn[j]--;
46             qmn1[j][++tmn[j]]=M[i][j];
47             qmn2[j][tmn[j]]=i;
48         }    
49         Hmx=Hmn=1;
50         Tmx=Tmn=0;
51         for(int j=1;j<N;j++){
52             while(Hmx<=Tmx&&Qmx1[Tmx]<=qmx1[j][hmx[j]]) Tmx--;
53             Qmx1[++Tmx]=qmx1[j][hmx[j]];
54             Qmx2[Tmx]=j;
55             while(Hmn<=Tmn&&Qmn1[Tmn]>=qmn1[j][hmn[j]]) Tmn--;
56             Qmn1[++Tmn]=qmn1[j][hmn[j]];
57             Qmn2[Tmn]=j;
58         }
59         for(int j=N;j<=B;j++){
60             while(Hmx<=Tmx&&Qmx2[Hmx]+N<=j) Hmx++;
61             while(Hmx<=Tmx&&Qmx1[Tmx]<=qmx1[j][hmx[j]]) Tmx--;
62             Qmx1[++Tmx]=qmx1[j][hmx[j]];
63             Qmx2[Tmx]=j;
64             while(Hmn<=Tmn&&Qmn2[Hmn]+N<=j) Hmn++;
65             while(Hmn<=Tmn&&Qmn1[Tmn]>=qmn1[j][hmn[j]]) Tmn--;
66             Qmn1[++Tmn]=qmn1[j][hmn[j]];
67             Qmn2[Tmn]=j;
68             ans=min(ans,Qmx1[Hmx]-Qmn1[Hmn]);
69         }        
70     }
71     printf("%d\n",ans);
72     return 0;
73 }

 

[BZOJ1047][HAOI2007]理想的正方形 二维单调队列

标签:online   大小   www   san   题目   正方形   string   span   mil   

原文地址:http://www.cnblogs.com/halfrot/p/7647730.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!