zoukankan      html  css  js  c++  java
  • [BZOJ1047][HAOI2007]理想的正方形 二维单调队列

    题目链接: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
    ",ans);
    72     return 0;
    73 }
  • 相关阅读:
    SqlServer数据库SQL语句(超详细)
    oracle sql语句
    MySQL常用SQL语句
    一路走来,风雨兼程,也谈笑风生
    个人第五次——测试别人的项目
    团队第五次——Alpha2的发布
    团队第四次——Alpha版本的发布
    团队第三次——系统设计
    第四次作业 结对编程
    团队第二次作业——需求分析
  • 原文地址:https://www.cnblogs.com/halfrot/p/7647730.html
Copyright © 2011-2022 走看看