当前位置: 首页 > news >正文

【高级数据结构】ST 表

前言

大部分 ST 表能解决的问题树状数组和线段树都能解决,只不过 ST 表的代码实现更加简单。

ST 表可以求解区间 $[l,r]$ 的最值问题等区间查询。

ST表

ST 表的定义

ST 表是利用倍增思想来解决区间问题的,这样可以缩短时间。

例如,我要求 $\large\max\limits_{i=l}^r a_i$ 的值,那么一般的做法就是从 $l$ 枚举到 $r$,然后用 $ans$ 来记录最大值,但是数据大了显然会超时

所以我们引出了一种新的数据结构 ST 表。

我们定义 $st_{i,j}$ 表示在序列的第 $i$ 项往后 $2^j$ 所包含的序列间的最大值

ST 表的处理

对于 $i=1$ 的情况来说,我们可以画个图:

那么我们可以发现 $st_{1,2} = \max(st_{1,1},st_{3,1})$ 转移过来,所以我们有以下递推式:

$$st_{i,j} = \max(st_{i,j-1},st_{i+2^{j-1},j-1})$$

但是这个 $i$ 有不能比 $n$ 大,所以当 $j$ 确定的时候,有 $i \in [1,n-2^j+1]$.

而 $2^j \le n$,所以有 $j \le \log_2 n$.

注意:我们要提前预处理这个数组。

void init(){ll len=log2(n);for(int j=1;j<=len;j++){for(int i=1;i+(1<<j)-1<=n;i++){st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);}}
}

ST 表的最值求法

对于 $\large\max\limits_{i=l}^r a_i$,我们也考虑用 ST 表的思想,通过两个 ST 表直接维护的区间,然后求最值即可。

那么我们将 $[l,r]$ 分为两个子区间,那么一个区间满足 $[l,r]$ 中 ST 表可维护的最大的子区间,也就是满足 $l+2^k-1 \le r$。

解这个不等式,则可以得出 $k \le \log_2 r-l+1$,这里直接令 $k = \log_2 r-l+1$ 即可。所以整个区间就是 $st_{l,k}$

现在只要反着找就可以了,因为对称性,所以 $k = \log_2 r-l+1$。

我们设该区间的起点为 $L$,那么一定满足 $L+2^k-1=r$。

解这个方程,可以知道 $L = r-2^k+1$,所以整个区间就是 $st_{r-2^k+1,k}$.

所以答案就为 $\max(st_{l,k},st_{r-2^k+1,k})$.

所以就可以写出完整代码了。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+5;
ll st[N][25];
ll n,q,k,ans,l,r;ll 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;
}void init(){ll len=log2(n);for(int j=1;j<=len;j++){for(int i=1;i+(1<<j)-1<=n;i++){st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);}}
}
int main(){n=read();q=read();for(int i=1;i<=n;i++) st[i][0]=read();init();while(q--){l=read(),r=read();k=log2(r-l+1);ans=max(st[l][k],st[r-(1<<k)+1][k]);printf("%lld\n",ans);}return 0;
}

这里我求的是区间最大值。

好了现在我们可以做点题了:

  • P3865 【模板】ST 表 && RMQ 问题

  • P1816 忠诚

  • P1890 gcd区间

  • P2880 [USACO07JAN] Balanced Lineup G

http://www.hskmm.com/?act=detail&tid=26061

相关文章:

  • 【高级算法】树形DP
  • 【高级数据结构】浅谈最短路
  • C++_基础
  • 2025电位仪厂家最新企业品牌推荐排行榜,纳米粒度及 Zeta 电位仪,Zeta 电位仪公司推荐
  • PCIe扫盲——物理层逻辑部分基础(二)
  • 前沿仿真未来趋势
  • StarRocks与Apache Iceberg:构建高效湖仓一体的实时分析平台 - 详解
  • 斑马打印机打印头更换教程
  • 构造中国剩余定理方程组的解
  • 2025粒度仪厂家最新品牌推荐榜,喷雾粒度分析仪, 激光粒度仪,激光粒度分析仪,纳米粒度仪公司推荐
  • MTK oppoR9m Smart Phone flash Tool 提示 ERROR: STATUS_ABORT(0xC0010002)
  • 二分图最大匹配 Dinic/EK算法
  • 基本Dos指令
  • 2025 年酒店一次性用品源头厂家最新推荐排行榜:含牙签牙线筷子套杯盖杯垫杯套外卖筷子印刷房卡套信封用品优质供应商盘点
  • 2025餐饮一次性用品厂家最新推荐排行榜:聚焦资质口碑与产品实力,助力餐饮企业精准选品!
  • 2025工伤诉讼律师事务所推荐:北京市信之源律所专业维权值得
  • 2025小程序开发公司最新推荐榜,优选杭州网博科技,兼顾用户体验与传播效果
  • 2025企业合同律师事务所推荐:北京信之源律所,专业靠谱之选
  • MTK oppoR9m Smart Phone flash Tool 提示 ERROR: STATUS_PRELOADER_INVALID(0xC0030004)
  • Docker 部署 PostgreSQL 数据库教程
  • 2025年软件外包平台解析:10个不同定位的真实情况
  • P3574 题解 | 贪心,树形 dp
  • 爱,在行动中生长,我们因爱而变得辽阔——《岛上书店》读后感
  • Ubuntu 下同名文件替换后编译链接到旧内容的现象分析 - 实践
  • Luogu P14007 「florr IO Round 1」查询游戏 题解 [ 蓝 ] [ 交互 ]
  • RK3588和FPGA桥片之间IO电平信号概率性不能通信原因 - 实践
  • 稀缺计算资源如何塑造机器学习优化专家
  • PWN手的成长之路-10-GDOUCTF 2023-Shellcode-短字节shellcode
  • 优雅的合并GIT分支
  • Docker部署