bzoj 1047 理想的正方形

也是单调队列
我之前分别用了优先队列和二位rmq做这题都超时了。。
最后学习了别人的题解

#include<bits/stdc++.h>
using namespace std;
#define sz(X) ((int)X.size())
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
const int N = 1e3+5;
const int INF = 0x3f3f3f3f;

int a,b,n;
int mp[N][N], mx[N][N], mi[N][N], t1[N], t2[N];
int ans;
int val[N], pos[N];
void pre() {
    for(int i = 1; i <= a; ++i) {
        int l = 1; int r = 1;
        for(int j = 1; j <= b; ++j) {
            while(l < r && val[r-1]<=mp[i][j]) r--;
            val[r]=mp[i][j]; pos[r] = j; r++;
            if(pos[l] == j-n) l++;
            if(j >= n) mx[i][j] = val[l];
        }
        l = 1; r = 1;
        for(int j = 1; j <= b; ++j) {
            while(l < r && val[r-1]>=mp[i][j]) r--;
            val[r]=mp[i][j]; pos[r] = j; r++;
            if(pos[l] == j-n) l++;
            if(j >= n) mi[i][j] = val[l];
        }
    }
}
void solve() {
    for(int i = n; i <= b; ++i) {
        int l = 1; int r = 1;
        for(int j = 1; j <= a; ++j) {
            while(l < r && val[r-1]<=mx[j][i]) r--;
            val[r]=mx[j][i]; pos[r]=j; r++;
            if(pos[l] == j-n) l++;
            if(j >= n) t1[j] = val[l];
        }
        l = 1; r = 1;
        for(int j = 1; j <= a; ++j) {
            while(l < r && val[r-1]>=mi[j][i]) r--;
            val[r]=mi[j][i]; pos[r]=j; r++;
            if(pos[l] == j-n) l++;
            if(j >= n) t2[j] = val[l];
        }
        for(int j = n; j <= a; ++j) ans = min(ans, abs(t1[j]-t2[j]) );
    }
}
int main(){
    while(~scanf("%d %d %d",&a,&b,&n)) {
        for(int i = 1; i <= a; ++i)
            for(int j = 1; j <= b; ++j)
                scanf("%d",&mp[i][j]);
        ans = INF;
        pre();
        solve();
        printf("%d\n",ans);
    }
    return 0;
}
posted @ 2016-11-03 15:11  basasuya  阅读(170)  评论(0编辑  收藏  举报