学习博客:https://blog.csdn.net/qq_31759205/article/details/75008659

RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干次询问RMQ(i,j),返回数列A中下标在区间[i,j]中的最小/大值。

本文介绍一种比较高效的ST算法解决这个问题。ST(Sparse Table)算法可以在O(nlogn)时间内进行预处理,然后在O(1)时间内回答每个查询。

第一步:预处理

设A[i]是要求区间最值的数列,F[i, j]表示从第i个数起连续2^j个数中的最大值。(DP的状态)

例如:

A数列为:3 2 4 5 6 8 1 2 9 7

F[1,0]表示第1个数起,长度为2^0=1的最大值,其实就是3这个数。同理 F[1,1] = max(3,2) = 3, F[1,2]=max(3,2,4,5) = 5,F[1,3] = max(3,2,4,5,6,8,1,2) = 8;

并且我们可以容易的看出F[i,0]就等于A[i]。(DP的初始值)

我们把F[i,j]分为两段,第一段为 i~i+2^(j-1)-1   第二段为 i+2^(j-1)~i+2^j-1  (长度都为2^(j-1)  ) 于是我们得到了状态转移方程:f[i,j]=max(f[i,j-1],f[i+2^(j-1),j-1] )。

2)查询

假如我们需要查询的区间为(i,j),那么我们需要找到覆盖这个闭区间(左边界取i,右边界取j)的最小幂(可以重复,比如查询1,2,3,4,5,我们可以查询1234和2345)。

因为这个区间的长度为j - i + 1,所以我们可以取k=log2( j - i + 1),则有:RMQ(i, j)=max{F[i , k], F[ j - 2 ^ k + 1, k]}。

举例说明,要求区间[1,5]的最大值,k = log2(5 - 1 + 1)= 2,即求max(F[1, 2],F[5 - 2 ^ 2 + 1, 2])=max(F[1, 2],F[2, 2]);

看代码:

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=1e5+;
int a[maxn];
int dp[maxn][];
void ST(int n)
{
for(int i=;i<=n;i++) dp[i][]=a[i];//初始化
for(int j=;(<<j)<=n;j++)//2^j
{
for(int i=;i+(<<j)-<=n;i++)//
{
dp[i][j]=max(dp[i][j-],dp[i+(<<(j-))][j-]);
}
}
return ;
}
int RMQ(int l,int r)
{
int k=log(r-l+);
return max(dp[l][k],dp[r-(<<k)+][k]);
}
int main()
{
memset(dp,,sizeof(dp));
int n;//长度为n的区间
cin>>n;
for(int i=;i<=n;i++) cin>>a[i];
ST(n);
int l,r;//查询的区间
cin>>l>>r;
cout<<RMQ(l,r)<<endl;
return ;
}

最新文章

  1. BZOJ 题目整理
  2. EasyUI 中点击取消按钮关闭Dialog(对话框窗口)
  3. java实现栈与队列
  4. netcat命令
  5. FlashFXP5_gr坑爹的故事
  6. Category
  7. 关于webview嵌入swf
  8. Java中的成员初始化顺序和内存分配过程
  9. NuGet学习笔记(1)——初识NuGet及快速安装使用(转)
  10. jekyll博客安装
  11. java nio的一个严重BUG(转)
  12. pixi.js
  13. XXS level9
  14. sql join 语句的小总结
  15. canvas 实现签名效果
  16. sql左右连接的区别
  17. 修改计算机名或IP后Oracle10g无法启动服务的解决办法
  18. 数据结构编程实验——chapter9-应用二叉树的基本概念编程
  19. 全文搜索引擎 Elasticsearch (三)logstash-input-jdbc同步数据 到elasticsearch
  20. 《C》数组

热门文章

  1. javascript总结48:正则表达式(RegExp)
  2. Java 栈与堆简介
  3. 编写高质量代码改善C#程序的157个建议——建议80:用Task代替ThreadPool
  4. Java50道经典习题-程序1 不死神兔
  5. C#线程/进程同步(lock、Mutex、Semaphore)
  6. 构建基于asp.net core 的docker应用并发布
  7. Python 单元测试 增强系统健壮性
  8. openedx使用中可能用到的一些资源
  9. centos 7 安装mysql5.6rpm格式
  10. mongodb driver2.5环境注意事项