当前位置: 首页 > 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.rkmt.cn/news/16871.html

相关文章:

  • 【高级算法】树形DP
  • 【高级数据结构】浅谈最短路
  • 代码随想录打卡|Day53 图论(Floyd 算法精讲 、A * 算法精讲 (A star算法)、最短路算法总结篇、图论总结 ) - 实践
  • expr命令全解
  • 斑马打印机打印头更换教程
  • 构造中国剩余定理方程组的解
  • 2025粒度仪厂家最新品牌推荐榜,喷雾粒度分析仪, 激光粒度仪,激光粒度分析仪,纳米粒度仪公司推荐
  • Xmind Pro v24 最新破解版下载及激活教程
  • 基本Dos指令
  • Ubuntu 下同名文件替换后编译链接到旧内容的现象分析 - 实践
  • Luogu P14007 「florr IO Round 1」查询游戏 题解 [ 蓝 ] [ 交互 ]
  • RK3588和FPGA桥片之间IO电平信号概率性不能通信原因 - 实践
  • 蒟蒻的第一篇随笔
  • oppoR9m刷Linux系统: 安装MTK USB VCOM驱动
  • 可视化大屏工具对比:GoView、DataRoom、积木JimuBI、Metabase、DataEase、Apache Superset 与 Grafana - 实践
  • [特殊字符] FFmpeg 学习笔记 - 详解
  • .NET周刊【9月第3期 2025-09-21】
  • 2025教练技术行业深度剖析:目标人群、费用与品牌选择
  • 免费开源Umi-OCR,离线采用,批量精准!
  • STM32外部中断(EXTI)以及旋转编码器的简介 - 指南
  • 神经网络中的梯度消失与梯度爆炸 - 实践
  • 基于 Chrome 浏览器扩展的Chroma简易图形化界面 - 实践
  • 详细介绍:go语言学习 第4章:流程控制
  • 《一元微积分》讲义习题
  • 开源量子模拟引擎:Quantum ESPRESSO本地部署教程,第一性原理计算轻松入门! - 实践
  • 详细介绍:QT常用控件(1)
  • 题解:P4779 【模板】单源最短路径(标准版)
  • 网关配置
  • 完整教程:docker创建postgreSql带多个init的sql
  • vscode的文心快码插件不错