POJ2019 Cornfields

题解:

二维RMQ中的ST算法的模板题

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<vector>
using namespace std;
using namespace std;
#define pb push_back
#define mp make_pair
#define se second
#define fs first
#define ll long long
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define ls o<<1
#define rs o<<1|1
#define SZ(x) ((int)(x).size())
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
typedef pair<int,int> P;
const double eps=1e-9;
const int maxn=50100;
const int N=1e9;
const int mod=1e9+7;

ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
//-----------------------------------------------------------------------------

int m[255][255];
int mi[255][255][8][8],mx[255][255][8][8];
int n,b,k,x,y;

void rmq_init()
{
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++) mi[i][j][0][0]=mx[i][j][0][0]=m[i][j];
    int Mx=(int)(log(n*1.0)/log(2.0));
    int My=(int)(log(n*1.0)/log(2.0));
    for(int i=0;i<=Mx;i++)
    for(int j=0;j<=My;j++)
    {
        if(i==0&&j==0) continue;
        for(int Row=1;Row+(1<<i)-1<=n;Row++)
        for(int Col=1;Col+(1<<j)-1<=n;Col++)
        {
            if(i)//因为已经算了只有一列时,每一一行的极值,那么有多列时,就不需要算行了
            {
                mx[Row][Col][i][j]=max(mx[Row][Col][i-1][j],mx[Row+(1<<(i-1))][Col][i-1][j]);
                mi[Row][Col][i][j]=min(mi[Row][Col][i-1][j],mi[Row+(1<<(i-1))][Col][i-1][j]);
            }
            else//当矩形只有一列时,那么算一行的极值
            {
                mx[Row][Col][i][j]=max(mx[Row][Col][i][j-1],mx[Row][Col+(1<<(j-1))][i][j-1]);
                mi[Row][Col][i][j]=min(mi[Row][Col][i][j-1],mi[Row][Col+(1<<(j-1))][i][j-1]);
            }
        }
    }
}

int rmq_max(int x1,int y1,int x2,int y2)
{
    int kx=(int)(log(x2-x1+1.0)/log(2.0));
    int ky=(int)(log(y2-y1+1.0)/log(2.0));
    x2=x2-(1<<kx)+1;
    y2=y2-(1<<ky)+1;
    return max(max(mx[x1][y1][kx][ky],mx[x1][y2][kx][ky]),max(mx[x2][y1][kx][ky],mx[x2][y2][kx][ky]));//算4部分,左右上下
}

int rmq_min(int x1,int y1,int x2,int y2)
{
    int kx=(int)(log(x2-x1+1.0)/log(2.0));
    int ky=(int)(log(y2-y1+1.0)/log(2.0));
    x2=x2-(1<<kx)+1;
    y2=y2-(1<<ky)+1;
    return min(min(mi[x1][y1][kx][ky],mi[x1][y2][kx][ky]),min(mi[x2][y1][kx][ky],mi[x2][y2][kx][ky]));
}

int main(){
    scanf("%d%d%d",&n,&b,&k);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++) scanf("%d",&m[i][j]);
    rmq_init();
    while(k--){
        scanf("%d%d",&x,&y);
        printf("%d\n",rmq_max(x,y,x+b-1,y+b-1)-rmq_min(x,y,x+b-1,y+b-1));
    }
    return 0;
}
时间: 2024-10-09 03:20:45

POJ2019 Cornfields的相关文章

POJ2019 Cornfields 二维ST表

网址:https://vjudge.net/problem/POJ-2019 题意: 给出一个矩阵,求左下角坐标为$(x,y)$,长度为$b$的正方形的包含的数的最大值和最小值. 题解: 一.二维ST表: 一维$ST$表可以快速处理一维$RMQ$问题,这次是二维问题,好,那就上二维$ST$表,构造方法和一维的类似.开一个四维数组,第一维第三维管横行,第二维第四维管纵行即可(反过来也行).然后处理完之后按照类似于一维$ST$表一样查询,查询四个小矩阵的最值就行,然后取最值,具体看代码. AC代码:

[poj2019]Cornfields(二维RMQ)

题意:给你一个n*n的矩阵,让你从中圈定一个小矩阵,其大小为b*b,有q个询问,每次询问告诉你小矩阵的左上角,求小矩阵内的最大值和最小值的差. 解题关键:二维st表模板题. 预处理复杂度:$O({n^2}\log n)$ 查询复杂度:$O(n)$ 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<iostream>

Cornfields poj2019 二维RMQ

Cornfields Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Submit Status Description FJ has decided to grow his own corn hybrid in order to help the cows make the best possible milk. To that end, he's looking to build the

Cornfields(poj2019)

Cornfields Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6798   Accepted: 3315 Description FJ has decided to grow his own corn hybrid in order to help the cows make the best possible milk. To that end, he's looking to build the cornfie

POJ 2019 Cornfields 二维RMQ

题目来源:POJ 2019 Cornfields 题意:求正方形二维区间最大最小值的差 思路:直接二维ST搞 试模版而已 #include <cstdio> #include <algorithm> #include <cmath> using namespace std; const int maxn = 255; int dp[maxn][maxn][8][8]; int dp2[maxn][maxn][8][8]; int a[maxn][maxn]; int n

RMQ [POJ 2019] Cornfields

Cornfields Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5516   Accepted: 2714 Description FJ has decided to grow his own corn hybrid in order to help the cows make the best possible milk. To that end, he's looking to build the cornfie

POJ 2019 Cornfields

相比以前的RMQ不同的是,这是一个二维的ST算法 #include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; #define N 300 int minbest[8][8][N][N]; int maxbest[8][8][N][N]; ///int lg[N]; int getmax(int a,int b,int c,int d) {

poj2019(二维RMQ)

题目连接:http://poj.org/problem?id=2019 只是增加一个维度,类比一维即可. 1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=270; 7 int p[maxn][maxn]; 8 int pmax[maxn][maxn][20]; 9 int

POJ 2019 Cornfields 二维线段树的初始化与最值查询

模板到不行.. 连更新都没有.. .存个模板. 理解留到小结的时候再写. #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack> #include <map> #