RMQ模板
2016-02-27 17:24
465 查看
RMQ:范围最小值问题。给出一个n个元素的数组A1,A2,...,An,设计一个数据结构支持查询操作Query(L,R):计算min{AL,AL+1,...,AR}。
每次用一个循环来求最小值显然不够快快,前缀和的思想也不能提高效率,这时候ST算法就派上用场了,它预处理的时间是O(nlogn),但是查询只需要Q(1),而且常数很小。
令dp[i][j]表示从i开始的,长度为2^j的一段元素中的最小值,递推公式:dp[i][j]=min{dp[i][j-1],dp[i+2^(j-1)][j-1]}
View Code
每次用一个循环来求最小值显然不够快快,前缀和的思想也不能提高效率,这时候ST算法就派上用场了,它预处理的时间是O(nlogn),但是查询只需要Q(1),而且常数很小。
令dp[i][j]表示从i开始的,长度为2^j的一段元素中的最小值,递推公式:dp[i][j]=min{dp[i][j-1],dp[i+2^(j-1)][j-1]}
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int Max = 100000 + 10; int maxsum[Max][32],minsum[Max][32]; int n,q,v; void RMQ_init() { for(int j = 1; (1 << j) <= n; j++) { for(int i = 1; i + (1 << j) - 1 <= n; i++) { maxsum[i][j] = max(maxsum[i][j - 1], maxsum[i + (1 << (j - 1))][j - 1]); minsum[i][j] = min(minsum[i][j - 1], minsum[i + (1 << (j - 1))][j - 1]); } } } int RMQ(int l, int r) { int k = 0; while( (1 << (k + 1)) <= (r - l + 1)) k++; int maxn = max(maxsum[l][k], maxsum[r - (1 << k) + 1][k]); int minn = min(minsum[l][k], minsum[r - (1 << k) + 1][k]); return maxn - minn; } int main() { while(scanf("%d%d", &n, &q) != EOF) { for(int i = 1; i <= n; i++) { scanf("%d", &v); minsum[i][0] = maxsum[i][0] = v; } RMQ_init(); while(q--) { int a,b; scanf("%d%d", &a, &b); printf("%d\n", RMQ(a,b)); } } return 0; }
View Code
相关文章推荐
- SecureCRT无法使用root账户远程连接ubuntu
- Android 使用小技巧之 :new Handler().postDelayed() 延迟intent跳转
- Android 一个改进的okHttp封装库
- 如何给Eclipse中添加库(jar包)
- 省市区(简版)
- 如何修改word的项目编号
- cordova build 报错:failed to notfy projectevluationlistener.afterevaluate<>.
- GCJ--Crazy Rows (2009 Round2 A)
- C++ 多态详解
- 关于RunLoop和Timer的一点理解
- 【刷题算法】不用+运算符求加法
- 广师Android群分享之自定义控件
- Android TagFlowLayout完全解析 一款针对Tag的布局
- Unity IOS端 注意点
- Xcode文档安装
- JS转义 escape()、encodeURI()、encodeURIComponent()区别详解
- nyoj586 poj2456二分+贪心
- GCJ--Minimum Scalar Product (2008 Round 1AA)
- 十大技巧优化Android App性能
- 创业的第一百三十一天