RMQ总结
题目描述
给定N个数的序列和M次询问,每次询问给定左右端点区间中的最大值
输入样例:
6 (N)
34 1 8 123 3 2
4 (M)
1 2
1 5
3 4
2 3
输出样例:
34
123
123
8
题目分析
虽然是另一类问题,但分析方法实际采用的是类似区间dp的方法,具体定义见下图
需要说明的是,图中所说的长度是指元素的个数,而非元素之间的间隔数。例如序列1,2,3,长度为3。其实这里无论选择元素个数还是间隔数都能解题,保证后续的下标计算对应上即可。

在上述初始化完成之后,对于一组询问,计算方法见下图。
很值得记忆的一点是当我们求解最值时,重合的区间并不会影响最终答案,我们只需保证所选区间能够覆盖整个区间即可。
下图中k的含义:满足 \(2^k <= len(R - L + 1)成立的最大值\),显然\(2^k * 2 > len\),假设不成立,那么当前的k就不是合法的k。所以我们选择的两个长度为\(2^k\)的区间一定是存在交集的,但是重复的数据对求解最大值并无影响,所以我们只需要在左右区间中找出最大值即可。

代码实现
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 2e5 + 10, M = 20;
int n, m;
int a[N];
int f[N][M];
void init()
{
/**
* 从转移方程可以看出,如果选择先预处理i,在更新f[i][j]时需要使用f[i + (2^j)][j - 1],显然是无法更新的
* 但是如果选择先预处理j,在更新f[i][j]时候所需要的f[][j-1]都已经更新完全了,是可以正常更新的
*/
for (int j = 0; j < M; ++ j) // 其实序列最长为200000,2^17 = 131072, 2^18 = 262144
for (int i = 1; i + (1 << j) - 1 <= n; ++ i)
if (!j) f[i][j] = a[i]; // 注意j=0时候对应长度为2^0=1,不是长度为0
else f[i][j] = max(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
}
int query(int l, int r)
{
int len = r - l + 1;
int k = log(len) / log(2); // log()求的是以10为底的对数
return max(f[l][k], f[r- (1 << k) + 1][k]);
}
int main()
{
cin >> n;
for (int i = 1; i <= n; ++ i) cin >> a[i];
init();
cin >> m;
while (m --)
{
int l, r;
cin >> l >> r;
cout << query(l ,r) << endl;
}
return 0;
}
RMQ总结的更多相关文章
- BZOJ 3489: A simple rmq problem
3489: A simple rmq problem Time Limit: 40 Sec Memory Limit: 600 MBSubmit: 1594 Solved: 520[Submit] ...
- UVA 11235Frequent values(RMQ)
训练指南P198 题意:给出一个非降序排列的整数数组a1, a2…… an,你的任务是对于一系列询问(i,j),回答ai, ai+1 ……aj 中出现的次数最多的次数 这题不仅学到了rmq的应用还学到 ...
- 51nod1174(RMQ)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1174 题意:中文题诶- 思路:RMQ模板题 关于RMQ: h ...
- 2016 ACM/ICPC Asia Regional Dalian Online 1008 Function 二分+RMQ
Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submissio ...
- Gym 100646 F Tanks a Lot RMQ
Problem F: Tanks a Lot Imagine you have a car with a very large gas tank - large enough to hold what ...
- (RMQ版)LCA注意要点
inline int lca(int x,int y){ if(x>y) swap(x,y); ]][x]]<h[rmq[log[y-x+]][y-near[y-x+]+]])? rmq[ ...
- 洛谷P2412 查单词 [trie树 RMQ]
题目背景 滚粗了的HansBug在收拾旧英语书,然而他发现了什么奇妙的东西. 题目描述 udp2.T3如果遇到相同的字符串,输出后面的 蒟蒻HansBug在一本英语书里面找到了一个单词表,包含N个单词 ...
- POJ3368Frequent values[RMQ 游程编码]
Frequent values Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17581 Accepted: 6346 ...
- [tem]RMQ(st)
倍增思想 代码中有两个测试 #include <iostream> #include <cmath> using namespace std; const int N=1e5; ...
- 二维RMQ
求二维ST表 ;k<=;k++) ;l<=;l++) ;i<=n;i++) ;j<=m;j++){ <<(l-)),m+),tx=min(n+,i+(<< ...
随机推荐
- nginx 添加ssl认证,访问静态资源 笔记
1.查看是否开启SSL模块, /usr/local/nginx/sbin ./nginx -V 2.没有开启,进入到nginx源码包目录下: 3编译 ./configure --prefix= ...
- bootstrapTable insertRow 新增行保留原数据
思路:保留原数据,然后新增行. var optionsxx = {//省略xxx: columns: [{ checkbox: true}, { field: 'id', title: '主键', c ...
- 【jmeter】请求域名解析失败,添加本地代理
jmeter HTTP请求URL中使用域名 http://xxx.xxx.xxx,异常:java.net.UnkownHostException 原因:请求域名没有被解析成功,该http请求没有通过本 ...
- a标签做锚点定位,有部分内容被置顶头部遮挡的解决方法
被遮挡的元素添加如下样式: /**这里假定头部高度是100px*/ position: relative;top: 100px;/**关键样式如下,我这里上面有加定位,如果没用定位,下面的数值需根据实 ...
- 2.21(html)
- SQL之查询
1. SQL之模糊查询 例如查询姓名时,不用输入全名,仅仅输入其中的一部分 语法: select 列名 from 表名 where 列名 like 匹配串 其中 匹配串用英文的单引号括起来 四种匹配模 ...
- echarts 图表 tooltip提示框,formatter自定义
自定义图表提示框样式, 自定义原因:series中有多个数据样式,那么提示框会展示多条. tooltip: { formatter(params) { let circle = `<span s ...
- git commit --amend适用场景详解
适用场景: 场景1.本地开发代码已提交,提交后发现这次提交的代码有问题,或者漏提交了一些文件,此时,希望达到以下目的: ①修改有问题的代码. ②补足漏提交的文件(一般是新增的文件没有git add . ...
- 学习使用数据库SQLServer (一)
小记一下学习使用数据库时遇到的问题 1.建表时未设置主键约束名,此时删表主键会遇到困难,不能简单使用 ALTER TABLE NAME DROP CONSTRAINT 约束名: 而是要先找到数据表中主 ...
- 微信小程序——石头剪刀布
博客班级 https://edu.cnblogs.com/campus/zjcsxy/SE2020 作业要求 https://edu.cnblogs.com/campus/zjcsxy/SE2020/ ...