首页 > 其他分享 >ST 表 && RMQ 问题

ST 表 && RMQ 问题

时间:2024-09-02 22:27:05浏览次数:5  
标签:ch 最大值 查询 RMQ && ST

倍增算法之:ST表 与 RMQ

讲解:

倍增思想,就是每次在原基础上往前“跳” \(2^n\) 步
RMQ参考 https://blog.csdn.net/qq_31759205/article/details/75008659
RMQ 问题,即区间最值查询问题,通常的做法(我会的做法)有 暴力、线段树……
这里介绍一种比较高效的算法:ST表。
ST 表可以做到 \(O(nlogn)\) 的预处理和 \(O(1)\) 的查询,是一种在码量和复杂度上都非常优秀的方法。

预处理:

  • 设 \(a\) 是要求区间最值的序列,\(f_{i,j}\) 表示从第 \(i\) 个数起连续 \(2^j\) 个数中的最大值。(DP状态)

for example:
a={3,2,4,5,6,8,1,2,9,7};
\(f_{1,0}\)表示从第一个数开始,长度为 \(2^0=1\) 的最大值,其实就是这个数 \(3\)。

  • 很容易看出 \(f_{i,0} = a_i\)。(DP的初始值)
  • 我们把 \(f_{i,j}\) 平均分成 \(2\) 段(因为 \(i\) 到 \(i+j-1\) 之间一定有偶数个数),从 \(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}\}\)

查询:

  • 假如我们要查询的区间为 \(i\) 到 \(j\),那么我们需要找到覆盖整个闭区间(左边界取 \(i\),右边界取 \(j\))的最小幂(可以重叠)

比如我们要查询 1,2,3,4,5 中的最大值,我们可以先查询 1,2,3,4 中的最大值,再查询 2,3,4,5 中的最大值,最后取 max

  • 因为这个区间长度为 \(j-i+1\),所以我们就可以取 \(k=log2(j-i+1)\) 则有 \(RMQ(i,j)= max\{f_{i,k},f_{j-2^k+1,k}\}\).

洛谷模板题传送门:ST 表 && RMQ 问题

代码:

#include<bits/stdc++.h>

using namespace std;

int n,m;
int f[100100][100];

inline int read()
{
	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-48;ch=getchar();
	}
	return x*f;
}

int main()
{
	n=read();m=read();
	for(int i=1;i<=n;i++)
	{
		f[i][0]=read();
	}
	for(int j=1;(1<<j)<=n;j++)
	{
		for(int i=1;i+(1<<j)-1<=n;i++)
		{
			f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
		}
	}
	while(m--)
	{
		int k=0;
		int l,r;
		l=read();r=read();
		while((1<<(k+1))<=r-l+1)k++;
		int ans=max(f[l][k],f[r-(1<<k)+1][k]);
		printf("%d\n",ans);
	}
	return 0;
 } 

标签:ch,最大值,查询,RMQ,&&,ST
From: https://www.cnblogs.com/lazy-ZJY0307/p/18369328

相关文章

  • 【Linux】Linux系统调试:如何选择strace和ltrace,全面对比
    在调试和诊断Linux程序时,strace和ltrace是两款常用的命令行工具。尽管它们都用于跟踪程序的行为,但它们的关注点和用途有所不同。本文将详细解析strace和ltrace的区别,帮助你选择适合的工具进行调试和诊断。......
  • pytest中用装饰器控制新增接口请求时间
    示例场景假设我们有一个提交数据的函数submit_data,我们希望在每次调用后等待一定的时间,以避免重复提交的问题。1.自动化提交接口的时候可以使用time.sleep()的方式这是最直接的方式,在函数调用后直接使用time.sleep()控制等待时间。importtimedefsubmit_data(da......
  • C++STL之list容器:基本使用及模拟实现
    目录有了vector,为何还需listlist的使用1,push_back、push_front、pop_back、pop_front的使用2,正向、反向、const正向、const反向迭代器的使用正向、反向迭代器的使用const正向、const反向迭代器的使用3,operator=赋值4,insert、erase任意位置的插入、删除5,迭代器失效(......
  • CF 2100-2400 strings 乱做
    CF1995DCases显然如果选了某个字符那么不妨选它出现的所有位置。check方式等价于相邻两个选择的位置间距\(\lek\),等价于连续\(k\)个必须选一个(最后一个必须选)枚举位置维护字符集是做不了的,状态数\(O(n2^c)\)无法优化考虑枚举字符集\(s\)。设原串连续\(k\)个字符的字......
  • Java API:System
    JavaAPI:System目录JavaAPI:System1System2示例代码1SystemSystem类包含几个有用的类字段和方法。它无法实例化。System类提供的设施包括标准输入,标准输出和错误输出流;访问外部定义的属性和环境变量;加载文件和库的方法;以及用于快速复制阵列的一部分的实用方法。......
  • ArrayList
    ArrayList目录ArrayList1ArrayList1.1ArrayList的构造方法和添加方法1.2ArrayList存储字符串并遍历1.3ArrayList存储学生对象并遍历2综合练习2.1学生管理系统实现步骤2.2学生类的定义2.3ArrayList02类的定义1ArrayList集合和数组的区别:​ 共同点:都是存储数据的......
  • 内存管理-14-内核文档翻译-2-memory-allocation.rst 和 gfp_mask-from-fs-io.rst
    一、memory-allocation.rstmsm-5.4/Documentation/core-api/memory-allocation.rst翻译:========================内存分配指南==========================Linux提供了各种用于内存分配的API。您可以使用`kmalloc()`或`kmem_cache_alloc()`系列分配小块,使用`vmalloc()`......
  • pycharm警告 :PytestConfigWarning: Unknown config option: makers
    一、PytestConfigWarning:Unknownconfigoption:makers虽然不影响执行测试用例,但是,追求完美的我很想解决掉他! 二、找报错的单词在哪,大概率这种报错在ini文件我的makers在pytest.ini。起初是想打标签,但是标签的注解是@pytest.mark.xxx,所以就把makers改成了markers,果然没有......
  • [Typescript Library] Navigate to Source Files instead of Declaration Files
    Thesolutionistomodifythe tsconfig.json filetoenable declarationMap underthe compilerOptions.//insidetsconfig.json{"compilerOptions":{"declaration":true,"declarationMap":true//...Byenabling ......
  • Stream List转Map
    需要注意的是:toMap如果集合对象有重复的key,会报错Duplicatekey....如:Student,Student1的id都为1002。可以用(k1,k2)->k1来设置,如果有重复的key,则保留key1,舍弃key2Map<Integer,Student>map=appleList.stream().collect(Collectors.toMap(Student::getId,a->a,(k1,k......