题目描述

给定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总结的更多相关文章

  1. BZOJ 3489: A simple rmq problem

    3489: A simple rmq problem Time Limit: 40 Sec  Memory Limit: 600 MBSubmit: 1594  Solved: 520[Submit] ...

  2. UVA 11235Frequent values(RMQ)

    训练指南P198 题意:给出一个非降序排列的整数数组a1, a2…… an,你的任务是对于一系列询问(i,j),回答ai, ai+1 ……aj 中出现的次数最多的次数 这题不仅学到了rmq的应用还学到 ...

  3. 51nod1174(RMQ)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1174 题意:中文题诶- 思路:RMQ模板题 关于RMQ: h ...

  4. 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 ...

  5. 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 ...

  6. (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[ ...

  7. 洛谷P2412 查单词 [trie树 RMQ]

    题目背景 滚粗了的HansBug在收拾旧英语书,然而他发现了什么奇妙的东西. 题目描述 udp2.T3如果遇到相同的字符串,输出后面的 蒟蒻HansBug在一本英语书里面找到了一个单词表,包含N个单词 ...

  8. POJ3368Frequent values[RMQ 游程编码]

    Frequent values Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17581   Accepted: 6346 ...

  9. [tem]RMQ(st)

    倍增思想 代码中有两个测试 #include <iostream> #include <cmath> using namespace std; const int N=1e5; ...

  10. 二维RMQ

    求二维ST表 ;k<=;k++) ;l<=;l++) ;i<=n;i++) ;j<=m;j++){ <<(l-)),m+),tx=min(n+,i+(<< ...

随机推荐

  1. ios怎么在自己公司网站扫描下载安装IPA安装包

    企业证书(或者99的证书,但是有100个设备限制)打包的IPA安装包,怎么发布给用户安装使用呢? 试了直接给用户.ipa包的链接,手机不能像安卓手机那样安装,平时我们测试放在蒲公英的包蒲公英应该是有做 ...

  2. UNIT TWO

    声明 基于8086的寄存器共14个16位的,分别是 ax  bx  cx  dx  (通用寄存器) si  di  bp  sp    (基址与变址寄存器) cs  ss  ds  es   (段寄存 ...

  3. 使用 GIT Bash Here 打tar包文件

    1.进入要被  打包的文件目录下 2.点击  Git Bash Here  ---> tar cvf server.tar server/ ok!!!!!!

  4. 前端vue框架上手记录

    ---恢复内容开始--- Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供: 通过 @vue/cli 搭建交互式的项目脚手架. 通过 @vue/cli + @vue/cli-se ...

  5. java中list对象不同属性去重合并

    需求:将list中对象的不同属性对应的值去重后,赋值给另一个属性! 实现效果如下图:

  6. iOS OC开发,文件的下载、预览

    /// 下载/打开 - (void)downloadActionWithDownloadString:(NSString *)downloadString{ //url : 下载地址 NSString ...

  7. Codeforces Round #843 (Div. 2) Problem C

    C. Interesting Sequence time limit per test 1 second memory limit per test 256 megabytes input stand ...

  8. vue、react配置gzip打包后,删除源文件deleteOriginalAssets: true,nginx需要的配置

    1.删除源文件后,配置了gzip,当配置gzip删除源文件后,解决前端history问题,就会出现所有的都返回html,请求js.css也会返回html,页面会报错,如下配置即可 location / ...

  9. dom和dom4j

    https://www.cnblogs.com/avivahe/p/5493060.html DOM.SAX.JDOM.DOM4J的区别

  10. git命令2

    git status git status -s git diff git diff --cached --添加到暂存区成为快照 git add -A git add . --删除被git追踪的文件 ...