一、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. pandas 的常用方法

    pandas的常用方法: 1.数据输入 2.数据查看 3.数据清洗 4.数据处理 5.数据提取 6.数据筛选 7.数据汇总 8.数据统计 9.数据输出 详情见: https://blog.csdn.n ...

  2. SpringBoot启动的时候出现log4j警告(配置文件找不到)

    SpringBoot启动的时候报如下的警告 在启动SpringBoot项目的时候,idea出现如下警告信息,也就是log4j 配置文件找不到的问题 log4j:WARN No appenders co ...

  3. CF1324F Maximum White Subtree 题解

    原题链接 简要题意: 给定一棵树,每个点有黑白两种颜色:对每个节点,求出包含当前节点的连通图,使得白点数与黑点数差最小.输出这些值. F题也这么简单,咳咳,要是我也熬夜打上那么一场...可惜没时间打啊 ...

  4. 使用docker构建双主mysql

    我们有的时候需要双主mysql, 这样无论哪个数据库出现了问题的话都可以继续使用数据库.把两个数据库挂到一个代理上面,这样哪个服务出问题了,另外一个就可以继续服务了.当然本文不是主要谈代理的,所以这个 ...

  5. 【webpack 系列】基础篇

    Webpack 基础篇 基本概念 Webpack 是一个现代 JavaScript 应用程序的静态模块打包器.当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每 ...

  6. 图-连通分量-DFS-并查集-695. 岛屿的最大面积

    2020-03-15 16:41:45 问题描述: 给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合.你可以假设二 ...

  7. js 的 new 干了什么

  8. 为什么我建议每个开发人员都需要学Python?

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://dzone.com/articles/10-reasons-why-every-d ...

  9. 技术再深入一点又何妨?一脸懵B的聊Actor

    记得上次深入 Resin 源码时,见到了Actor 字眼,当时主要从 Resin 中抽取关键架构,就屏蔽了 Actor 相关代码.未曾想这两天研究 flink 的运行架构以及源码,再次与 Actor ...

  10. FileReader与URL.createObjectURL实现图片、视频上传前预览

    之前做图片.视频上传预览常用的方案是先把文件上传到服务器,等服务器返回文件的地址后,再把该地址字符串赋给img或video的src属性,这才实现所谓的文件预览.实际上这只是文件“上传后再预览”,这既浪 ...