首页 > 编程语言 >ST算法

ST算法

时间:2022-10-24 22:00:09浏览次数:51  
标签:int max 最大值 ST 算法 区间 最值

ST算法

ST算法可以在 \(O(N \log N)\) 时间的预处理后,以 \(O(1)\) 的时间复杂度在线回答区间最值问题

状态转移

一个序列的子区间个数显然有 \(N^2\) 个,根据倍增思想,我们可以在这个空间里选择一些 \(2\) 的整数次幂的位置作为代表值。

状态:\(f[i][j]\) :数组 \(a\) 在子区间 \([i, i+2^j-1]\) 中的最大值

初值:显然 \(f[i][0] = a[i]\),即 \(a\) 在子区间 \([i, i]\) 中的最大值

状态转移:\(f[i][j] = max(f[i][j-1],f[i+2^{j-1}][j-1])\)

Example:

假设现有一数组 \(a = \{ 5,3,7,9,6,4,1,2\}\),可以得到如下表格

\(i\) \(a\) \(ST[i][0]\) \(ST[i][1]\) \(ST[i][2]\) \(ST[i][3]\)
\(1\) \(5\) \(5\) \(5\) \(9\) \(9\)
\(2\) \(3\) \(3\) \(7\) \(9\) \
\(3\) \(7\) \(7\) \(9\) \(9\) \
\(4\) \(9\) \(9\) \(9\) \(9\) \
\(5\) \(6\) \(6\) \(6\) \(6\) \
\(6\) \(4\) \(4\) \(4\) \ \
\(7\) \(1\) \(1\) \(2\) \ \
\(8\) \(2\) \(2\) \ \ \

若想求出 \(ST[1][2]\) 的值,即区间 \([1,4]\) 中的最值

我们可以取 \(ST[1][1]\) 和 \(ST[3][1]\) 的最大值作为 \(ST[1][2]\) 的值

因为 \(ST[1][1]\) 代表区间 \([1,2]\) 中的最大值,\(ST[3][1]\) 代表区间 \([3,4]\) 中的最大值

取两个数的最大值,即为区间 \([1,4]\) 中的最值

由此可得状态转移方程:\(f[i][j] = max(f[i][j-1],f[i+2^{j-1}][j-1])\)

照应上述例子,\(3 = 1 + 2^{2-1}\),恰好满足。

初始化

根据状态转移方程,可得如下代码:

void ST_pre()
{
	for(int i=1;i<=n;i++)
		ST[i][0]=a[i];
	int t=log2(n)+1;
	for(int j=1;j<=t;j++)
		for(int i=1;i<=n-(i<<j)+1;i++)
			ST[i][j]=max(ST[i][j-1],ST[i+(1<<(j-1))][j-1]);
}

查询

当询问区间 \([l,r]\) 中的最值时,令区间长度 \(x = r-l+1\)

我们可以先计算出一个\(k\),满足 \(2^k \leq x \leq 2^{k+1}\)

即将区间分为 比 \(x\) 小的 \(2\) 的最大整数幂剩下的部分

再将剩下的部分进行分解,直到不能再分为止

然后依次返回每个区间的最值,取最大值即可

int ST_query(int l,int r)
{
	int k=log2(r-l+1);
	return max(f[l][k],f[r-(1<<k)+1][k]);
}

标签:int,max,最大值,ST,算法,区间,最值
From: https://www.cnblogs.com/LanSky6/p/16823171.html

相关文章

  • dremio parquet zstd 压缩支持尝试
    主要是dremioparquetzstd压缩支持尝试,说明下思路,大家可以参考修改ExecConstants配置sabot/kernel/src/main/java/com/dremio/exec/ExecConstants.java......
  • OpenStack云计算平台框架
    概: OpenStack是包含很多独立组件的一个云计算平台框架。在安装组件前,需要先将框架搭建出来,才能向其中放置组件。   搭建openstack云计算平台框架一、安装open......
  • 2.4 RedisAPI之list
    1.简介字符串键值结构(keyvalue)特点有序可重复左右两边都可插入和删除2.命令从列表右端插入值rpushkeyvalue1value2......valueN时间复杂度为O(1~n)从列表左端插入值l......
  • 2.2 RedisAPI之string
    1.简介字符串键值结构(keyvalue)value的值小于512m,一般建议一个key-value的大小为100k使用场景缓存计数器分布式锁2.命令设置key-value不管key是否存在都设置setkeyvalue......
  • C++算法之旅、01 入门篇
    使用胡凡主编的《算法笔记》教材。题目均为第三章题目。TEST//ProblemAddress#define_CRT_SECURE_NO_WARNINGS#include<cstdio>intmain(){return0;}PAT......
  • Oracle-11g静默安装-db_install.rsp详解
    Oracle11g静默安装文件配置和解释,大部分的数据是不需要变更的,只变更你需要改动的地方,和图形界面安装结合起来,可快速理解。详解快速查看#标注响应文件版本,这个版本必须和要安......
  • C语言入门-1-编译器的基本使用(Dev c++和visual studio)
    一、Devc++打开软件点击文件,新建,项目 选择Console点击helloworld,勾选c项目,名称自行输入点击确定后出现文件位置,自行安放在文件夹里保存后即可进行编译运......
  • 实验7:基于REST API的SDN北向应用实践
    (一)基本要求编写Python程序,调用OpenDaylight的北向接口实现以下功能。(1)利用Mininet平台搭建下图所示网络拓扑,并连接OpenDaylight。(2)下发指令删除s1上的流表数据#!/us......
  • 第4章 最基础的分类算法-k近邻算法 kNN
    4-1k近邻算法基础 ......
  • 「ARC151E」Keep Being Substring - 题解
    题意题目链接:Link。有一个序列\(A\)。\(X,Y\)是给定的\(A\)的两个子串,每次可以在\(X\)的开头或末尾增添或删除一个数字,且需满足任意时刻\(X\)非空且为\(A\)的......