一、ST算法

ST算法(Sparse Table Algorithm)是用于解决RMQ问题(区间最值问题,即Range Maximum/Minimum Question)的一种著名算法。

ST算法能在复杂度为\(O(NlogN)\)的预处理后,以\(O(1)\)的复杂度在线处理序列区间内的最大值/最小值。

值得注意的是,ST算法并不能处理需要修改点权的区间最值问题。

  • ST表的实现同样依据倍增思想,设\(f(i,j)\)表示序列下标区间为\([i,i+2^{j}-1]\)的最值,即从\(i\)在内的\(2^j\)个数的最大值。

    递推过程中的转移方程与LCA的思想类似,新的区间最值由原区间翻倍推出,转移方程为:

\[f[i,j]=max(f[i,j-1],f[i+2^{j-1},j-1])
\]

\[f[i,j]=min(f[i,j-1],f[i+2^{j-1},j-1])
\]

图示(很良心):

  • 当我们询问任意区间[l,r]的最大/最小值的时候,我们计算出一个\(k\),使得\(2^k \lt r-l+1\leq 2^{k+1}\),这样保证我们的覆盖长度\(2^k\)是区间能覆盖最大的长度。此时询问两个区间\([l,r]\),\([r-2^{k}+1,r]\)的极值就能求出该区间的最大/最小值,尽管区间可能重叠,由于我们求的是最大/最小值,因此重叠区间对答案没有影响。

    图示(查询[3,23]区间最值):


二、ST算法の具体实现

1. 初始化

for(int i=1;i<=n;i++){
scanf("%d",a[i]);
f[i][0]=a[i];//[i,i]的最值就是a[i]
}

2. 求出ST表

int maxn=log(n)/log(2)+1;
for(int j=1;j<maxn;j++)
for(int i=1;i<=n-(1<<j)+1;i++)
f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);

3. 询问

询问[l,r]的最大值,ans为答案。

int k=log(r-l+1)/log(2);
int ans=max(f[l][k],f[r-(1<<k)+1][k]);

附:log(n)函数求出的值是\(lgn\),为了求出\(log_2n\),我们可以使用换底公式:\(log_2n=\frac{lgn}{lg2}\)解决,时间复杂度为\(O(1)\)。

除此之外,如果有同学认为\(log()\)常数大,我们同样可以手动求出\(log_2n\)的值:

Log[0]=-1;
for(int i=1;i<=n;i++) Log[i]=Log[i>>1]+1;

三、例题

例1:P3865 【模板】ST表

Code:

#include<bits/stdc++.h>
const int logN=25;
const int N=1e7;
using namespace std;
int a[N],f[N][logN];
int m,n,x,y;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
f[i][0]=a[i];
}
int maxn=log(n)/log(2)+1;
for(int j=1;j<maxn;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]);
for(int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
int k=log(y-x+1)/log(2);
printf("%d\n",max(f[x][k],f[y-(1<<k)+1][k]));
}
return 0;
}

例2:P2880 [USACO07JAN]平衡的阵容Balanced Lineup

分别预处理出最大值和最小值,询问时相减。

Code:

#include<bits/stdc++.h>
using namespace std;
int n,q,f[50010][25],g[50010][25],a[50010];
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),f[i][0]=g[i][0]=a[i];
int maxn=log(n)/log(2)+1;
for(int j=1;j<=maxn;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]);
g[i][j]=min(g[i][j-1],g[i+(1<<(j-1))][j-1]);
}
for(int i=1,l,r;i<=q;i++){
scanf("%d%d",&l,&r);
int k=log(r-l+1)/log(2);
int ans=max(f[l][k],f[r-(1<<k)+1][k])-min(g[l][k],g[r-(1<<k)+1][k]);
printf("%d\n",ans);
}
return 0;
}

[总结]RMQ问题&ST算法的更多相关文章

  1. RMQ的ST算法

    ·RMQ的ST算法    状态设计:        F[i, j]表示从第i个数起连续2^j个数中的最大值    状态转移方程(二进制思想):        F[i, j]=max(F[i,j-1], ...

  2. RMQ(ST算法)

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

  3. RMQ之ST算法模板

    #include<stdio.h> #include<string.h> #include<iostream> using namespace std; ; ],M ...

  4. RMQ问题+ST算法

    一.相关定义 RMQ问题 求给定区间的最值: 一般题目给定许多询问区间. 常见问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大 ...

  5. RMQ问题——ST算法

    比赛当中,常会出现RMQ问题,即求区间最大(小)值.我们该怎样解决呢? 主要方法有线段树.ST.树状数组.splay. 例题 题目描述 2008年9月25日21点10分,酒泉卫星发射中心指控大厅里,随 ...

  6. RMQ问题ST算法 (还需要进一步完善)

    /* RMQ(Range Minimum/Maximum Query)问题: RMQ问题是求给定区间中的最值问题.当然,最简单的算法是O(n)的,但是对于查询次数很多(设置多大100万次),O(n)的 ...

  7. RMQ 问题 ST 算法(模板)

    解决区间查询最大值最小值的问题 用 $O(N * logN)$ 的复杂度预处理 查询的时候只要 $O(1)$ 的时间  这个算法是 real 小清新了   有一个长度为 N 的数组进行 M 次查询 可 ...

  8. RMQ之ST算法

    #include <stdio.h> #include <string.h> ; int a[N]; ]; inline int min(const int &a, c ...

  9. Round #4 RMQ问题ST算法

    前几天群里看到有人问[JSOI2008]最大数,一道很简单的问题,线段树无脑做,但是看到了动态ST,emmm,学学吧,听大佬说了下思路,还好,不难的: 四道题都可以用其他数据结构或做法代替,例如线段树 ...

随机推荐

  1. payload分离免杀

    shellcode loader 借助第三方加载器,将shellcode加载到内存中来执行. https://github.com/clinicallyinane/shellcode_launcher ...

  2. 汉诺塔Java实现

    public class Hanoi { public static void main(String[] args ) { Hanoi hanoi = new Hanoi(); hanoi.hano ...

  3. 如何利用python实现为每行添加行数编号

    可能还有更好的方法,在这里我是这么写的,针对小文件可以,但是如果文件内容太多,这种方法感觉不太好 先把所有的数据读取出来,然后利用W覆盖写入模式打开文件进行写入 遍历枚举类型数据后,默认是从0开始,然 ...

  4. [算法]移除指定元素&strSr()的实现

    移除指定元素 题目 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度. 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原 ...

  5. ES6全面讲解

    写在之前.讲解了比较常用的ES6知识点,可以快速的入门.有两个比较复杂的知识点(promise,generator)则是留在了其他文章中,在里面详细讲解. 介绍 1.历史 ​ 1.ECMAScript ...

  6. iOS 页面流畅技巧(1)

    一.屏幕显示图像原理 首先明确两个概念:水平同步信号.垂直同步信号. CRT 的电子枪按照上图中的方式,从上到下一行一行的扫描,扫描完成后显示器就呈现一帧画面,随后电子枪回到初始位置继续下一次的扫描. ...

  7. [POI2014][树形DP]FarmCraft

    题目 In a village called Byteville, there are houses connected with N-1 roads. For each pair of houses ...

  8. B 火车

    时间限制 : 10000 MS   空间限制 : 565536 KB 评测说明 : 1.5s,512m 问题描述 A 国有n 个城市,城市之间有一些双向道路相连,并且城市两两之间有唯一路径.现在有火车 ...

  9. Docker Swarm 资源管理

    Docker Swarm Docker Swarm是Docker官方项目之一,是使用SwarmKit构建的Docker引擎内置的集群管理和编排工具,提供Docker容器集群服务,是Docker官方对容 ...

  10. Light of future-冲刺Day 7

    目录 1.SCRUM部分: 每个成员进度 SCRUM 会议的照片 签入记录 代码运行截图 用户浏览界面 订单详情界面 管理员浏览界面 新增后台界面 2.PM 报告: 时间表 燃尽图 任务总量变化曲线 ...