【线段树】浅谈区间问题3
来源:互联网 发布:uri malformed 解决js 编辑:程序博客网 时间:2024/05/17 06:17
本文就来讲解一下什么是RMQ吧……
RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就是说,RMQ问题是指求区间最值的问题。
RMQ运用的是倍增的思想
比如说已知数组[a]: 3 5 2 4 7 6
开一个F二维数组,F[i][j]表示从第i个数开始,共j^2个数中的最值。
来讲讲RMQ代码的实现
1.构建F数组
有点像dp,但又不完全是。i,j是枚举的,我们假设我们要求F[i][j]并且之前的所有数组已经被求出了。
那么F[i][j]={ F[i][j-1] || F[i+j^2][j-1] }
为什么呢?就是将所求区间分为前后俩个部分来实现,很容易懂对吧。
2.查询
查询(i,j)区间内的最值
那么设k为区间在F数组中的中点
k=log(j-i+1)/log(2)
ans={ F[i][k]||F[j-k^2+1][k] }
跟上面求F数组极其相似,将所需区间分为俩半,然后合并
分析 时间代价 O(logn*n 构造F + q 查询q次 )
优点:时间代价远小于线段树
缺点:不支持修改
上一道躶题
【问题描述】
每天,农夫 John 的N(1 <= N <= 50,000)头牛总是按同一序列排队. 有一天, John 决定让一些牛们玩一场飞盘比赛. 他准备找一群在对列中为置连续的牛来进行比赛. 但是为了避免水平悬殊,牛的身高不应该相差太大. John 准备了Q (1 <= Q <= 180,000) 个可能的牛的选择和所有牛的身高 (1 <= 身高 <= 1,000,000). 他想知道每一组里面最高和最低的牛的身高差别. 注意: 在最大数据上, 输入和输出将占用大部分运行时间.
【问题分析】
RMQ维护最大最小俩个域即可
#include <iostream>#include <cstdio>#include <cmath>using namespace std;const int N=50001;const int logN=17;int n,q; int h[N],Fmax[N][logN],Fmin[N][logN];int readin(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}void read(){ int i; n=readin(); q=readin(); for (i=1;i<=n;i++) h[i]=readin(); return;}void RMQ(){ int i,j; for (i=1;i<=n;i++) { Fmax[i][0]=h[i]; Fmin[i][0]=h[i]; } for (j=1;j<=logN;j++) for (i=1;i<=n;i++) if (i+(i<<j)-1<=n) { Fmax[i][j]=max(Fmax[i][j-1],Fmax[i+(1<<(j-1))][j-1]); Fmin[i][j]=min(Fmin[i][j-1],Fmin[i+(1<<(j-1))][j-1]); } return;}void query(int a,int b){ int k=log(b-a+1)/log(2); int mmin,mmax; mmin=min(Fmin[a][k],Fmin[b-(1<<k)+1][k]); mmax=max(Fmax[a][k],Fmax[b-(1<<k)+1][k]); printf("%d\n",mmax-mmin); return;}void work(){ int i,a,b; for (i=1;i<=q;i++) { a=readin(); b=readin(); query(a,b); } return;}int main(){ read(); RMQ(); work(); return 0;}
- 【线段树】浅谈区间问题3
- 【线段树】浅谈区间问题(1)
- 【线段树】浅谈区间问题(2)
- CodeForces 438D 浅谈区间取模线段树
- 数据结构--线段树--区间涂色问题
- 【最小区间问题】 RQM 和 线段树
- 线段树+RMQ区间最值问题
- 线段树解决区间覆盖问题
- 线段树的区间合并问题
- poj2528&&zoj1610 线段树区间染色问题
- 线段树求解区间值问题
- Tunnel Warfare(线段树区间合并问题)
- 浅谈区间问题
- [CodeVS1082] 线段树练习3(区间修改+询问区间和)
- 线段树 区间合并
- 线段树区间修改
- 线段树 区间合并
- 线段树区间更新
- Mysql中的LIKE用法字符匹配
- 在android studio中加载本地html文件
- cdecl、stdcall、fastcall函数调用约定区别
- js中opener和parent的区别
- Class类文件结构、类加载机制以及字节码执行
- 【线段树】浅谈区间问题3
- Android简单自定义圆形和水平ProgressBar
- 插入有序 的 三个位置
- 新的 cocoaPods 使用的命令 mac os 10.11 以后
- 重构Pomelo游戏框架的Unity客户端
- Android java 中如何优雅的结束线程
- iOS 多线程篇8—GCD的常见用法
- [bzoj2453]【NOI2011模拟7.23】维护队列
- Git中.gitignore的配置语法