POJ 2019(二维RMQ)
2016-04-13 17:37
381 查看
Cornfields
Submit Status
Description
给出一个N*N (N<=250)的方阵,以及K(<=100000)个询问。每次询问如下:以(Xi,Yi)为左上角,边长为B的子方阵中,最大值和最小值的差是多少?
注意对于所有的询问,B都是一个定值。
Input
第一行N,B(<=N),K。含义如上。
接下来N行N列的一个矩阵,每个数<=250。
接下来K行表示询问,每行两个数Xi, Yi 表示询问的方阵的左上角。
Output
一行一个正整数,含义如上。
Sample Input
Sample Output
Source
USACO 2003 March Green
题解:二维RMQ的模板题,直接套模板
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include<algorithm>
#define N 500
using namespace std;
int pmax
[11], pmin
[10], a
, n,m, q, width,high,maxans, minans;
//n*m的矩阵,查询点(a,b)为左上角的,查询宽度为width,宽度为high的子矩阵rmq
void init_rmq()
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
pmax[i][j][0] = pmin[i][j][0] = a[i][j];
for (int i = 1; i <= n; i++)
for (int k = 1; (1 << k) <= m; k++)
for (int j = 1; j + (1 << k) - 1 <= m; j++)
{
pmax[i][j][k] = max(pmax[i][j][k - 1], pmax[i][j + (1 << (k - 1))][k - 1]);
pmin[i][j][k] = min(pmin[i][j][k - 1], pmin[i][j + (1 << (k - 1))][k - 1]);
}
}
void read()
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%d", &a[i][j]);
init_rmq();
}
void askrmq(int a, int b)
{
int k = (int)(log(double(width)) / log(2.0));
maxans = 0; minans = int(1e9);
int l = b, r = b + width - 1;
for (int i = a; i<a + high; i++)
{
maxans = max(maxans, max(pmax[i][l][k], pmax[i][r - (1 << k) + 1][k]));
minans = min(minans, min(pmin[i][l][k], pmin[i][r - (1 << k) + 1][k]));
}
}
void go()
{
for (int i = 1, a, b; i <= q; i++)
{
scanf("%d%d", &a, &b);
askrmq(a, b);
printf("%d\n", maxans - minans);
}
}
int main()
{
#ifdef CDZSC
freopen("i.txt", "r", stdin);
#endif // CDZSC
while (scanf("%d%d%d", &n, &width, &q) != EOF)
{
m = n;
high = width;
read();
go();
}
return 0;
}
Time Limit: 1000MS | Memory Limit: 30000KB | 64bit IO Format: %I64d & %I64u |
Description
给出一个N*N (N<=250)的方阵,以及K(<=100000)个询问。每次询问如下:以(Xi,Yi)为左上角,边长为B的子方阵中,最大值和最小值的差是多少?
注意对于所有的询问,B都是一个定值。
Input
第一行N,B(<=N),K。含义如上。
接下来N行N列的一个矩阵,每个数<=250。
接下来K行表示询问,每行两个数Xi, Yi 表示询问的方阵的左上角。
Output
一行一个正整数,含义如上。
Sample Input
5 3 1 5 1 2 6 3 1 3 5 2 7 7 2 4 6 1 9 9 8 6 5 0 6 9 3 9 1 2
Sample Output
5
Source
USACO 2003 March Green
题解:二维RMQ的模板题,直接套模板
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include<algorithm>
#define N 500
using namespace std;
int pmax
[11], pmin
[10], a
, n,m, q, width,high,maxans, minans;
//n*m的矩阵,查询点(a,b)为左上角的,查询宽度为width,宽度为high的子矩阵rmq
void init_rmq()
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
pmax[i][j][0] = pmin[i][j][0] = a[i][j];
for (int i = 1; i <= n; i++)
for (int k = 1; (1 << k) <= m; k++)
for (int j = 1; j + (1 << k) - 1 <= m; j++)
{
pmax[i][j][k] = max(pmax[i][j][k - 1], pmax[i][j + (1 << (k - 1))][k - 1]);
pmin[i][j][k] = min(pmin[i][j][k - 1], pmin[i][j + (1 << (k - 1))][k - 1]);
}
}
void read()
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%d", &a[i][j]);
init_rmq();
}
void askrmq(int a, int b)
{
int k = (int)(log(double(width)) / log(2.0));
maxans = 0; minans = int(1e9);
int l = b, r = b + width - 1;
for (int i = a; i<a + high; i++)
{
maxans = max(maxans, max(pmax[i][l][k], pmax[i][r - (1 << k) + 1][k]));
minans = min(minans, min(pmin[i][l][k], pmin[i][r - (1 << k) + 1][k]));
}
}
void go()
{
for (int i = 1, a, b; i <= q; i++)
{
scanf("%d%d", &a, &b);
askrmq(a, b);
printf("%d\n", maxans - minans);
}
}
int main()
{
#ifdef CDZSC
freopen("i.txt", "r", stdin);
#endif // CDZSC
while (scanf("%d%d%d", &n, &width, &q) != EOF)
{
m = n;
high = width;
read();
go();
}
return 0;
}
相关文章推荐
- getLastKnownLocation 返回null
- stopPropagation, preventDefault 和 return false 的区别
- CardVIew 卡片式布局
- hive中的一些基本问题解决方法
- iOS 警告收录及科学快速的消除方法
- 一款基于HTML5的Web 3D开发工具
- Socket通讯
- HBase Rowkey的散列与预分区设计
- HDU 1281 棋盘游戏(二分图匹配)
- [bzoj2555]substring 解题报告
- Oracle 死锁的检测查询及处理
- UITextView 控制输入字数总结
- 第六周项目4-静态成员应用
- android之Notification实现
- 使用lua调用mongoDB 实例
- Docker中的网络详解以及与OpenStack网络对比
- SSH限制普通用户到家目录
- Struts2的There is not Action mapped for namespace [/] 错误
- java 内部类的使用
- 倒计时四天——2983:谁是你的潜在朋友