(赛前练手#4)BZOJ1047 [HAOI2007]理想的正方形(单调队列)

版权声明:转载请声明出处,谢谢支持 https://blog.csdn.net/Dreamstar_DS/article/details/83246003

不说了,就是二维滑动窗口…
求MAX,先对每行(列)进行滑动窗口,再对每列(行)进行滑动窗口
MIN同理

AC Code:

#include<bits/stdc++.h>
#include <deque>
#define rg register
#define il inline
#define ll long long
#define maxn 2000005
using namespace std;
il ll read(){rg ll x = 0 , w = 1;rg char ch = getchar();while (ch < '0' || ch > '9'){if (ch == '-') w = -1;ch = getchar();}while (ch >= '0' && ch <= '9'){x = (x << 3) + (x << 1) + ch - '0';ch = getchar();}return x * w;}
ll f[1005][1005],maxx[1005][1005],minn[1005][1005],maxy[1005][1005],miny[1005][1005];
struct node{
    ll v;int index;	
};
int main(){
    ll a = read() , b = read() , k = read();
    for (rg int i = 1;i<=a;++i) 
        for (rg int j=1;j<=b;++j)
            f[i][j] = read();
    deque<node> q;
    for (int i=1;i<=a;++i){
     	q.clear();
    	for (int j=1;j<=b;++j)
        {
    		while (!q.empty() && f[i][j] >= q.back().v)	q.pop_back();
   	 		q.push_back((node){f[i][j],j});
    		if (!q.empty() && j > k && q.front().index <= j - k) q.pop_front();
    		if (j >= k){
                maxx[i][j - k + 1] = q.front().v;
            }
    	}
    }
    for (int j = 1 ; j <= b - k + 1 ; ++j){
     	q.clear();
    	for (rg int i = 1 ; i <= a ; ++i)
        {
    		while (!q.empty() && maxx[i][j] >= q.back().v)	q.pop_back();
   	 		q.push_back((node){maxx[i][j],i});
    		if (!q.empty() && i > k && q.front().index <= i - k) q.pop_front();
    		if (i >= k){
                maxy[i - k + 1][j] = q.front().v;
            }
    	}
    }
    for (int i=1;i<=a;++i){
     	q.clear();
    	for (int j=1;j<=b;++j)
        {
    		while (!q.empty() && f[i][j] <= q.back().v)	q.pop_back();
   	 		q.push_back((node){f[i][j],j});
    		if (!q.empty() && j > k && q.front().index <= j - k) q.pop_front();
    		if (j >= k){
                minn[i][j - k + 1] = q.front().v;
            }
    	}
    }
    for (int j = 1 ; j <= b - k + 1 ; ++j){
     	q.clear();
    	for (rg int i = 1 ; i <= a ; ++i)
        {
    		while (!q.empty() && minn[i][j] <= q.back().v)	q.pop_back();
   	 		q.push_back((node){minn[i][j],i});
    		if (!q.empty() && i > k && q.front().index <= i - k) q.pop_front();
    		if (i >= k){
                miny[i - k + 1][j] = q.front().v;
            }
    	}
    }
	rg ll res = 99999999999ll , ansmin , ansmax;
    for (int i=1;i <= a - k + 1;++i){
        for (int j=1;j <= b - k + 1;++j){
           	ansmin = 99999999999ll,ansmax = -9999999999ll;
            ansmin = min(ansmin,miny[i][j]);
            ansmax = max(ansmax,maxy[i][j]);
            res = min(res , ansmax - ansmin);
        }
    }
    cout<<res;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Dreamstar_DS/article/details/83246003