Range Minimum/Maximum Query (RMQ) - Sparse Table 算法
2011-07-13 16:07
453 查看
算法的复杂度为O(nlogn + Q)。
代码如下:
测试结果:
练习可以参考 POJ 3264
这里是另外的一个版本,ST表是横着的,上面的是竖着的。
代码如下:
/* * ===================================================================================== * * Filename: RMQ_st.CPP * * Description: Range Min/Max Query - st algorithm * * Version: 1.0 * Created: 07/13/11 13:33:45 * Revision: none * Compiler: gcc * * Author: nomad2 * * ===================================================================================== */ #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int N = 200001; int a , d[20]; int st [20]; void readIn(int n) { int i; for(i = 0; i < n; i++) { scanf("%d", &a[i]); } } void initRMQ(int n) { int i, j; for(d[0] = 1, i = 1; i < 21; i++) { d[i] = 2 * d[i-1]; } for(i = 0; i < n; i++) { st[i][0] = a[i]; } int k = int(log(double(n))/log(2)) + 1; for(j = 1; j < k; j++) { for(int i = 0; i < n; i++) { if(i + d[j-1] - 1 < n) { st[i][j] = max(st[i][j-1], st[i + d[j-1]][j-1]); } else { break; // st[i][j] = st[i][j-1]; } } } for(int i = 0; i < n; i++) { for(int j = 0; j < k; j++) { printf("%d ", st[i][j]); } printf("\n"); } } void query(int Q) { int i; for(i = 0; i < Q; i++) { int x, y, k; scanf("%d%d", &x, &y); k = int(log(double(y-x+1))/log(2.0)); printf("%d\n", max(st[x][k], st[y - d[k]+1][k])); } } int main() { int n, Q; while(scanf("%d%d", &n, &Q) != EOF) { readIn(n); initRMQ(n); query(Q); } return 0; }
测试结果:
[pa004306: ] >> cat input1 8 3 4 5 7 2 1 3 6 9 1 2 2 4 3 7 [pa004306: ] >> cat input1 |./a.exe 4 5 7 5 7 7 7 7 7 2 2 6 1 3 9 3 6 9 6 9 9 9 9 0 7 7 9
练习可以参考 POJ 3264
这里是另外的一个版本,ST表是横着的,上面的是竖着的。
#include <cstdio> #include <algorithm> using namespace std; const int N = 100; int st[20] , ln , val ; int n = 9; void initrmq(int n) { int i, j, k, sk; ln[0] = ln[1] = 0; for(i = 0; i < n; i++) { st[0][i] = val[i]; } for(i = 1, k = 2; k < n; i++, k <<= 1) { printf("k is %d\n", k); for(j = 0, sk = (k>>1); j < n; j++, sk++) { st[i][j] = st[i-1][j]; if(sk < n && st[i][j] > st[i-1][sk]) { st[i][j] = st[i-1][sk]; } } ln[0] = -1; for(j = (k>>1); j < k; j++) { ln[j] = ln[(k>>1)-1] + 1; } } ln[0] = 0; /* for(j = (k>>1) + 1; j <= k; j++) { ln[j] = ln[k>>1] + 1; } */ } void print() { for(int i = 0; i < 5; i++) { for(int j = 0; j < n; j++) { printf("%d ", st[i][j]); } printf("\n"); } printf("ln is "); for(int i = 0; i < n; i++) { printf("%d ", ln[i]); } printf("\n"); } // min of (val[x]...val[y]) int query(int x, int y) { int bl = ln[y-x+1]; return min(st[bl][x], st[bl][y-(1<<bl)+1]); } int main() { int v[] = {9, 5, 6, 7, 8, 3, 4, 2, 1}; n = sizeof(v)/sizeof(int); for(int i = 0; i < n; i++) { val[i] = v[i]; } initrmq(n); print(); for(int x = 0; x < n; x++) { //for(int y = x; y < n; y++) int y = x + 1; { printf("min between %d and %d is %d\n", x, y, query(x, y)); } } }
相关文章推荐
- RMQ (Range Minimum/Maximum Query)问题的ST(Sparse Table)解法
- RMQ(Range Minimum/Maximum Query)解决方法之一稀疏表(sparse table)
- RMQ (Range Minimum/Maximum Query)算法
- RMQ (Range Minimum/Maximum Query)算法(转)
- RMQ (Range Minimum/Maximum Query)算法(查询区间最值)
- RMQ (Range Minimum/Maximum Query)算法
- RMQ (Range Minimum/Maximum Query)算法(转)
- RMQ (Range Minimum/Maximum Query)算法(转)
- RMQ (Range Minimum/Maximum Query)算法(转)
- RMQ (Range Minimum/Maximum Query)算法
- RMQ (Range Minimum/Maximum Query)算法(转)
- RMQ (Range Minimum/Maximum Query)算法(转)
- RMQ (Range Minimum/Maximum Query)算法(转)
- 算法 RMQ(Range Minimum Query)问题:Sparse-Table算法
- RMQ (Range Minimum/Maximum Query)算法(转)
- RMQ (Range Minimum/Maximum Query)算法(转)
- RMQ (Range Minimum/Maximum Query)算法(转)
- RMQ (Range Minimum/Maximum Query)算法(转)
- RMQ (Range Minimum/Maximum Query)算法(转)
- RMQ (Range Minimum/Maximum Query)算法(转)