POJ 2019

简单的RMQ,可我怎么写都WA。不明白,找了一个和我相似的贴过了,要赶着去外婆家。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#define eps 1e-5
#define MAXN 255
#define MAXM 111111
#define INF 1000000000
using namespace std;
int mx[MAXN][MAXN][8], mi[MAXN][MAXN][8];
int n, b, q, a, c;
void rmqinit()
{
    int l = int(log(double(n)) / log(2.0)) ;
    for(int k = 1; k <= n ; k++)
        for(int j = 1; j <= l; j++)
            for(int i = 1; i + (1 << (j - 1))- 1 <= n; i++)
            {
                mx[k][i][j] = max(mx[k][i][j - 1], mx[k][i + (1 << (j - 1 ))][j - 1]) ;
                mi[k][i][j] = min(mi[k][i][j - 1], mi[k][i + (1 << (j - 1 ))][j - 1]) ;
            }
}
int rmqmax(int lx, int ly, int rx, int ry) // lx, ly为左上角的点 rx ry为右下角的点
{
    int l = int(log(double(ry - ly + 1)) / log(2.0));
    int ret = -1;
    for(int k = lx; k <= rx ; k++)
        ret = max(ret, max(mx[k][ly][l], mx[k][ry - (1 << l) + 1][l]));
    return ret;
}
int rmqmin(int lx, int ly, int rx, int ry) // lx, ly为左上角的点 rx ry为右下角的点
{
    int l = int(log(double(ry - ly + 1)) / log(2.0));
    int ret = INF;
    for(int k = lx; k <= rx ; k++)
        ret = min(ret, min(mi[k][ly][l], mi[k][ry - (1 << l) + 1][l]));
    return ret;
}
int main()
{
    while(scanf("%d%d%d", &n, &b, &q) != EOF)
    {
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
            {
                scanf("%d",&a);
                mx[i][j][0] = mi[i][j][0] = a ;
            }
        rmqinit();
        while(q--)
        {
            scanf("%d%d", &a, &c) ;
            int rx = a + b - 1;
            if(rx > n) rx = n;
            int ry = c + b - 1;
            if(ry > n) ry = n;
            printf("%d\n", rmqmax(a, c, rx, ry) - rmqmin(a, c, rx, ry)) ;
        }
    }
    return 0;
}

  

MINE:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <string.h>
#include <queue>
#include <cmath>
#include <vector>
using namespace std;

int num[255][255];
int f1[255][255][30];
int f2[255][255][30];
int n,b,q;
const int inf=1000000000;

int rmq_max(int p,int i, int j) {
     int k = (int)(log(double(j-i+1)) / log(2.0)), t1;
     t1 = max(f1[p][i][k], f1[p][j - (1<<k) + 1][k]);
     return t1;
}
int rmq_min(int p,int i, int j) {
     int k = (int)(log(double(j-i+1)) / log(2.0)), t2;
     t2 = min(f2[p][i][k], f2[p][j - (1<<k) + 1][k]);
     return t2;
}

int main(){
	int l,u;
	while(scanf("%d%d%d",&n,&b,&q)!=EOF){
		int k = (int) (log((double)n) / log(2.0));
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++)
			scanf("%d",&num[i][j]);
 		    for(int j = 0; j < n; j++) {
            	f1[i][j][0] = num[i][j];
            	f2[i][j][0] = num[i][j];
			}
			for(int p = 1; p <= k; p++) {
				for(int t = 0; t + (1 << p) - 1 < n; t++)   {
				 	int	m = t + (1 << (p - 1));
					f1[i][t][p] = max(f1[i][t][p-1], f1[i][m][p-1]);
					f2[i][t][p] = min(f2[i][t][p-1], f2[i][m][p-1]);
				}
			}
		}
		int maxn=-1,minn=inf;
		for(int i=1;i<=q;i++){
			scanf("%d%d",&u,&l);
			l--;u--;
			for(int p=u;p<(u+b);p++){
				maxn=max(maxn,rmq_max(p,l,l+b-1));
				minn=min(minn,rmq_min(p,l,l+b-1));
			}
			printf("%d\n",maxn-minn);
		}
	}
	return 0;
}

  

时间: 2024-10-11 16:34:04

POJ 2019的相关文章

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

相比以前的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) {

二维 ST POJ 2019

题目大意:给你一个n*n的矩阵,每次给你一个点(x,y),以其为左上角,宽度为b的矩阵中最小的数值和最大数值的差是多少?  一共k个询问. 思路:简单的二维st. 定义dp(i,j,k,L)表示以(i,j)为左上角,宽度为(2^k, 2^L)的区间内的最大(小)值. //看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #include<cstdio> #include<cstring> #include<vector> #include&

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

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

poj 2019 二维rmq *

题目大意:给出一个N*N矩形,每个格子上有一个价值.询问一个b*b的矩形在左上角的位置(x,y),(x+b-1,y+b-1)这一部分的最大值-最小值是多少. 模板题 1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 int val[255][255]; 8 int mm[255];

POJ 2019 Cornfields (RMQ?反正我暴力了)

[题意简述]:题目告诉我们很多数据,有N,表示这个农场的大小N*N,还有B,表示我们要测量的那个小正方形的大小B*B,还有K,代表我们要在这个N*N的农场上测几组数据.要测量的那个小正方形的左上角的坐标给你了,x和y.现在让我们求出在这个B*B的小正方形中最大的数值减去最小的数值结果是多少 [分析]:这本应是个二维的RMQ问题: http://blog.csdn.net/u013749862/article/details/39008855 下面是别人用RMQ的解法: http://kmplay

POJ 2019 Power of Cryptography

技巧. #include<iostream> #include<cmath> using namespace std; double n,p; int main(){ while(cin>>n>>p){ cout<<pow(p,1/n)<<endl; } }

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

ACM第一阶段学习内容

一.知识目录 字符串处理 ................................................................. 3 1.KMP 算法 ............................................................ 3 2.扩展 KMP ............................................................ 6 3.Manacher 最长回文子串 .......