POJ--2019--Cornfields【二维RMQ】

链接:http://poj.org/problem?id=2019

题意:给你一个n*n的矩阵,q次询问,每次询问给出左上角的坐标,询问以这个点为左上角的b*b的子矩阵中最大值和最小值的差。

思路:二维RMQ的基本应用,网上找的模板

这道题是USACO的,数据很水,暴力也能过。

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 260
#define eps 1e-7
#define INF 0x3F3F3F3F      //0x7FFFFFFF
#define LLINF 0x7FFFFFFFFFFFFFFF
#define seed 1313131
#define MOD 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

int a[MAXN][MAXN];
int maxm[MAXN][MAXN][11],minm[MAXN][MAXN][11];
void RMQ(int num){
    int i,j,k;
    for(i = 1; i <= num; i++){
        for(j = 1; j <= num; j++){
            maxm[i][j][0] = minm[i][j][0] = a[i][j];
        }
    }
    for(i = 1; i <= num; i++){
        for(k = 1; (1 << k) <= num; k++){
            for(j = 1; j + (1 << k) - 1 <= num; j++){
                maxm[i][j][k] = max(maxm[i][j][k-1],maxm[i][j+(1<<(k-1))][k-1]);
                minm[i][j][k] = min(minm[i][j][k-1],minm[i][j+(1<<(k-1))][k-1]);
            }
        }
    }
}
int main(){
    int i,j,n,b,q;
    int top,left;
    scanf("%d%d%d",&n,&b,&q);
    for(i = 1; i <= n; i++){
        for(j = 1; j <= n; j++){
            scanf("%d", &a[i][j]);
        }
    }
    RMQ(n);
    while(q--){
        scanf("%d%d", &top, &left);
        int k = (int)(log(double(b))/log(2.0));
        int minans = INF, maxans = 0;
        int x = left, y = left + b - 1;
        for(i = top; i < top + b; i++){
            maxans = max(maxans,max(maxm[i][x][k],maxm[i][y-(1<<k)+1][k]));
            minans = min(minans,min(minm[i][x][k],minm[i][y-(1<<k)+1][k]));
        }
        printf("%d\n",maxans - minans);
    }
    return 0;
}
时间: 2024-07-28 20:09:50

POJ--2019--Cornfields【二维RMQ】的相关文章

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

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

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

[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

HDU 2888:Check Corners(二维RMQ)

http://acm.hdu.edu.cn/showproblem.php?pid=2888 题意:给出一个n*m的矩阵,还有q个询问,对于每个询问有一对(x1,y1)和(x2,y2),求这个子矩阵中的最大值,和判断四个角有没有等于这个最大值的. 思路:二维RMQ模板题.注意内存卡的挺紧的. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5

【bzoj1047】[HAOI2007]理想的正方形 二维RMQ

题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数.每行相邻两数之间用一空格分隔.100%的数据2<=a,b<=1000,n<=a,n<=b,n<=1000 输出 仅一个整数,为a*b矩阵中所有“n*n正方形区域中的最大整数和最小整数的差值”的最小值. 样例输入 5 4 2 1 2 5 6 0 1

[hdu2888]二维RMQ

题意:求矩形内最大值.二维RMQ. 1 #pragma comment(linker, "/STACK:10240000,10240000") 2 3 #include <iostream> 4 #include <cstdio> 5 #include <algorithm> 6 #include <cstdlib> 7 #include <cstring> 8 #include <map> 9 #include

HDU2888 Check Corners(二维RMQ)

有一个矩阵,每次查询一个子矩阵,判断这个子矩阵的最大值是不是在这个子矩阵的四个角上 裸的二维RMQ 1 #pragma comment(linker, "/STACK:1677721600") 2 #include <map> 3 #include <set> 4 #include <stack> 5 #include <queue> 6 #include <cmath> 7 #include <ctime> 8

P2216 [HAOI2007]理想的正方形(二维RMQ)

题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一行为3个整数,分别表示a,b,n的值 第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数.每行相邻两数之间用一空格分隔. 输出格式: 仅一个整数,为a*b矩阵中所有“n*n正方形区域中的最大整数和最小整数的差值”的最小值. 输入输出样例 输入样例#1: 5 4 2 1 2 5 6 0 17 16 0 16 17 2 1 2 10 2