二维RMQ(Range Minimum Query)
来源:互联网 发布:网络女神雅典娜 编辑:程序博客网 时间:2024/05/29 04:47
二维RMQ(Range Minimum Query)
先来看一维情形:
给定一个数组x以及大量的查询,查询内容是任意区间内的最小值,例如数组长度为n,则查询为从x[a]到x[b]中的最小值,0<=a<b<n, a, b 任意。
问题是如何进行预处理,使得每次查询时间为O(1)。
解法:计算出所有长度为2^i的区间的最小值,则任[a,b]区间可以拆为两个长度为2^i的区间的并集,i=log(b-a)。
例如查询1到100间的最小值,[1,64],[37,100]的最小值已知,则[1,100]的最小值,为这两者中的小者。
算法的空间和时间复杂度均为O(logN)
由此可以推演到二维情况,给一个n*n的矩阵,要查询任意子矩阵的最小值。
解法类似,计算出所有大小为2^i*2^j的子矩阵,然后查询时候,每个子矩阵可以看成是四个预处理矩阵的并集,查询时间仍然为O(1),而预处理的复杂度为O(N*N*logN*lonN)
典型的题目如zoj的2859题,
Given an n*n matrix A, whose entries Ai,j are integer numbers ( 1 <= i <= n, 1 <= j <= n ). An operation FIND the minimun number in a given ssub-matrix.
Input
The first line of the input contains a single integer T , the number of test cases.
For each test case, the first line contains one integer n (1 <= n <= 300), which is the sizes of the matrix, respectively. The next n lines with n integers each gives the elements of the matrix.
The next line contains a single integer N (1 <= N <= 1,000,000), the number of queries. The next N lines give one query on each line, with four integers r1, c1, r2, c2 (1 <= r1 <= r2 <= n, 1 <= c1 <= c2 <= n), which are the indices of the upper-left corner and lower-right corner of the sub-matrix in question.
Output
For each test case, print N lines with one number on each line, the required minimum integer in the sub-matrix.
代码:
#include<iostream>
#include<cstdio>
using namespace std;
int mat[310][310];
int table[9][9][310][310];
int n;
int b[] = {
1, 2, 4, 8, 16, 32, 64, 128, 256, 512
};
inline int minn(int a, int b)
{
return a < b ? a : b;
}
int mylog(int n)
{
if (n == 0)
return 0;
int i = 0;
while (true) {
if (n < b[i])
return i - 1;
++i;
}
return -1;
}
void rmq()
{
// 从小到大计算,保证后来用到的都已经计算过
for(int i=0;i<=mylog(n);++i) // width
for(int j=0;j<=mylog(n);++j){ //height
if(i==0 && j==0)
continue;
for(int ii=0;ii+b[j]<=n;++ii)
for(int jj=0;jj+b[i]<=n;++jj){
if(i==0)
table[i][j][ii][jj]=minn(table[i][j-1][ii][jj],table[i][j-1][ii+b[j-1]][jj]);
else
table[i][j][ii][jj]=minn(table[i-1][j][ii][jj],table[i-1][j][ii][jj+b[i-1]]);
}
}
}
int main()
{
int T;
cin >> T;
while (T--) {
cin >> n;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j) {
cin >> mat[i][j];
table[0][0][i][j] = mat[i][j];
}
rmq();
long N;
cin >> N;
int r1, c1, r2, c2;
for (int i = 0; i < N; ++i) {
scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
--r1;
--c1;
--r2;
--c2;
int w=mylog(c2-c1+1);
int h=mylog(r2-r1+1);
printf("%d/n",minn(table[w][h][r1][c1],minn(table[w][h][r1][c2-b[w]+1],minn(table[w][h][r2-b[h]+1][c1],table[w][h][r2-b[h]+1][c2-b[w]+1]))));
}
}
return 0;
}
- 二维RMQ(Range Minimum Query)
- Range Minimum Query (RMQ)
- Range Minimum Query (RMQ)
- Range Minimum Query( RMQ )
- Range Minimum Query(RMQ)
- RMQ(Range Minimum Query)
- Range Minimum Query (RMQ)
- RMQ(Range Minimum Query)
- RMQ (Range Minimum/Maximum Query)问题
- RMQ (Range Minimum/Maximum Query)算法
- RMQ (Range Minimum/Maximum Query)算法
- RMQ ( Range Maximum/Minimum Query ) 详解
- RMQ(Range Minimum Query)问题
- RMQ(Range Minimum/Maximum Query)算法(nyist119)
- RMQ(range maximum/minimum query)算法
- RMQ (Range Minimum/Maximum Query)问题
- RMQ (Range Minimum/Maximum Query)算法
- RMQ (Range Minimum/Maximum Query)算法
- 数码证照中的头像自动切割原理与实现
- C/C++ 程序设计员应聘常见面试试题深入剖析二
- FC7 samba服务器的配置
- 常用的一些javascript小技巧
- 重置VS2005
- 二维RMQ(Range Minimum Query)
- Windows GDI与DC
- 第一个blog
- Test
- 一些琐碎的东西
- 动态向OjbectDataSource添加参数(转eddie005)
- 软件项目管理之七:产品规格说明书
- tomcat 配置
- 位图文件读写综述