POJ - 2019 Cornfields 二维RMQ

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38013346/article/details/82120200

题意

n n
( x , y ) b


题解

S T
R M Q

C o d e 1
d p [ i ] [ j ] [ k ] ( i , j ) 2 k

/*
 * dp[i][j][k] 表示以 点(i,j)为左上顶点的长度为1<<k的正方形最大或最小值
 */
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 300;
int maze[maxn][maxn],n;
struct ST {
    int Max[maxn][maxn][10],Min[maxn][maxn][10];
    int mm[maxn],kk[20];
    void init() {
        mm[0] = -1;
        for(int i=0;i<n;i++) {
            mm[i+1] = (((i+1) & i) == 0)? mm[i] + 1:mm[i];
            for(int j=0;j<n;j++) {
                Max[i][j][0] = Min[i][j][0] = maze[i][j];
            }
        }
        // for(int i=0;i<=n;i++) printf("%d ",mm[i]);printf("\n");
        kk[0] = 1;
        for(int i=1;i<20;i++) kk[i] = kk[i-1]*2;
        for(int k=1;kk[k]<=n;k++) {
            for(int i=0;i+kk[k]-1<n;i++) {
                for(int j=0;j+kk[k]-1<n;j++) {
                    Max[i][j][k] = max(max(Max[i][j][k-1],Max[i][j+kk[k-1]][k-1]),
                                max(Max[i+kk[k-1]][j][k-1],Max[i+kk[k-1]][j+kk[k-1]][k-1]));
                    Min[i][j][k] = min(min(Min[i][j][k-1],Min[i][j+kk[k-1]][k-1]),
                                min(Min[i+kk[k-1]][j][k-1],Min[i+kk[k-1]][j+kk[k-1]][k-1]));
                }
            }
        }
    }
    int query(int x,int y,int l) {
        int k = mm[l];
        int maxa = max(max(Max[x][y][k],Max[x][y+l-kk[k]][k]),max(Max[x+l-kk[k]][y][k],Max[x+l-kk[k]][y+l-kk[k]][k]));
        int mina = min(min(Min[x][y][k],Min[x][y+l-kk[k]][k]),min(Min[x+l-kk[k]][y][k],Min[x+l-kk[k]][y+l-kk[k]][k]));
        // printf("%d %d %d\n",k,maxa,mina);
        return maxa - mina;
    }

}st;
int b,k;
int main()
{
    while(~scanf("%d%d%d",&n,&b,&k)) {
        for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&maze[i][j]);
        st.init();
        while(k--) {
            int x,y;scanf("%d%d",&x,&y);
            printf("%d\n",st.query(x-1,y-1,b));
        }
    }
    return 0;
}

这里写图片描述

C o d e 2
d p [ i ] [ j ] [ k ] [ d ]   ( i , j ) 2 d 2 k

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef short int sint;
const int maxn = 255;
int maze[maxn][maxn];
int n;
struct ST {
    sint Min[maxn][maxn][8][8],Max[maxn][maxn][8][8];
    sint mm[maxn],kk[8];
    void init() {
        mm[0] = -1;kk[0] = 1;
        for(int i=0;i<n;i++) {
            mm[i+1] = (((i+1) & i) == 0) ? mm[i] + 1: mm[i];
            kk[i+1] = kk[i] * 2;
            for(int j=0;j<n;j++) {
                Min[i][j][0][0] = Max[i][j][0][0] = maze[i][j];
            }
        }
        for(int k=0;kk[k]<=n;k++) {
            for(int d=0;kk[d]<=n;d++) if(k+d){
                for(int i=0;i+kk[k]-1<n;i++) {
                    for(int j=0;j+kk[k]-1<n;j++) {
                        if(k) {
                            Max[i][j][k][d] = max(Max[i][j][k-1][d],Max[i+kk[k-1]][j][k-1][d]);
                            Min[i][j][k][d] = min(Min[i][j][k-1][d],Min[i+kk[k-1]][j][k-1][d]);
                        }
                        else {
                            Max[i][j][k][d] = max(Max[i][j][k][d-1],Max[i][j+kk[d-1]][k][d-1]);
                            Min[i][j][k][d] = min(Min[i][j][k][d-1],Min[i][j+kk[d-1]][k][d-1]);
                        }
                    }
                }
            }
        }
    }
    sint max_query(int x1,int y1,int x2,int y2) {
        sint k1 = mm[x2-x1+1],k2 = mm[y2-y1+1];
        x2 = x2 - kk[k1] + 1;
        y2 = y2 - kk[k2] + 1;
        return max(max(Max[x1][y1][k1][k2],Max[x1][y2][k1][k2]),max(Max[x2][y1][k1][k2],Max[x2][y2][k1][k2]));
    }
    sint min_query(int x1,int y1,int x2,int y2) {
        sint k1 = mm[x2-x1+1],k2 = mm[y2-y1+1];
        x2 = x2 - kk[k1] + 1;
        y2 = y2 - kk[k2] + 1;
        return min(min(Min[x1][y1][k1][k2],Min[x1][y2][k1][k2]),min(Min[x2][y1][k1][k2],Min[x2][y2][k1][k2]));
    }
}st;
int b,k;
int main()
{
    while(~scanf("%d%d%d",&n,&b,&k)) {
        for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&maze[i][j]);
        st.init();
        while(k--) {
            int x,y;scanf("%d%d",&x,&y);
            x--;y--;
            printf("%d\n",st.max_query(x,y,x+b-1,y+b-1)-st.min_query(x,y,x+b-1,y+b-1));
        }
    }
    return 0;
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/m0_38013346/article/details/82120200