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 }
  • 相关阅读:
    USACO 3.3 A Game
    USACO 3.3 Camelot
    USACO 3.3 Shopping Offers
    USACO 3.3 TEXT Eulerian Tour中的Cows on Parade一点理解
    USACO 3.3 Riding the Fences
    USACO 3.2 Magic Squares
    USACO 3.2 Stringsobits
    USACO 3.2 Factorials
    USACO 3.2 Contact
    USACO 3.1 Humble Numbers
  • 原文地址:https://www.cnblogs.com/halfrot/p/7647730.html
Copyright © 2011-2022 走看看