luogu 2216 理想的正方形 单调队列(其实没有DP)

Posted asdic

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu 2216 理想的正方形 单调队列(其实没有DP)相关的知识,希望对你有一定的参考价值。

#include<bits/stdc++.h>

using namespace std;

const int A=1050;
const int N=105;
int a,b,n;
int g[A][A],q[A][N],Q[A][N];
int head[A],tail[A];
int Head[A],Tail[A];

inline int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch==-)f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;}

int main(){
    a=read(),b=read(),n=read();
    for(register int i=1;i<=a;i++)
    for(register int j=1;j<=b;j++) g[i][j]=read();
    
    for(register int j=1;j<=b;j++){
       head[j]=tail[j]=1;
       Head[j]=Tail[j]=1;
       for(register int i=1;i<=n-1;i++){
           while(head[j]<=tail[j]&&g[i][j]<=g[q[j][tail[j]]][j]) tail[j]--;
           q[j][++tail[j]]=i;
           while(Head[j]<=Tail[j]&&g[i][j]>=g[Q[j][Tail[j]]][j]) Tail[j]--;
           Q[j][++Tail[j]]=i;
       }
    }
    int ans=0x3f3f3f3f;
    for(register int i=n;i<=a;i++){
        for(register int j=1;j<=b;j++){
            while(head[j]<=tail[j]&&q[j][head[j]]<i-n+1) head[j]++;
            while(head[j]<=tail[j]&&g[i][j]<=g[q[j][tail[j]]][j]) tail[j]--;
            q[j][++tail[j]]=i;
            
            while(Head[j]<=Tail[j]&&Q[j][Head[j]]<i-n+1) Head[j]++;
            while(Head[j]<=Tail[j]&&g[i][j]>=g[Q[j][Tail[j]]][j]) Tail[j]--;
            Q[j][++Tail[j]]=i;
        }
        for(register int j=n;j<=b;j++){
            int mi=0x3f3f3f3f,mx=-0x3f3f3f3f;
            for(register int k=j-n+1;k<=j;k++){
                mi=min(mi,g[q[k][head[k]]][k]);
                mx=max(mx,g[Q[k][Head[k]]][k]);
            }
            ans=min(ans,mx-mi);
        }
    }
    printf("%d
",ans);return 0;
} 

二维单调队列

以上是关于luogu 2216 理想的正方形 单调队列(其实没有DP)的主要内容,如果未能解决你的问题,请参考以下文章

洛谷OJ 2216 理想的正方形 单调队列(二维)

luogu2216 [HAOI2007]理想的正方形

luogu P2216 [HAOI2007]理想的正方形

P2216 [HAOI2007]理想的正方形 - 单调队列

[luoguP2216] [HAOI2007]理想的正方形(二维单调队列)

P2216 [HAOI2007] 理想的正方形(单调队列)