ST表,稀疏表,用于求解经典的RMQ问题。即区间最值问题。

Problem:

给定n个数和q个询问,对于给定的每个询问有l,r,求区间[l,r]的最大值。.

Solution:

主要思想是倍增和区间dp。

状态:dp[i][j] 为闭区间[i,i+2^j-1]的最值。

这个状态与转移方程的关系很大,即闭区间的范围涉及到了转移方程的简便性。

转移方程:dp[i][j]=max(dp[i][j-1],dp[i+2^(j-1)][j-1])

这是显然的,但这里有个细节:第一个项的范围为[i,i+2^(j-1)-1],即第i个数到第i+2^(j-1)个数的前一个数,而第二个项的范围是[i+2^(j-1),i+2^j-1]。这里容易弄混,所以导致无法理解整个方程,或者写错。

询问:[l,r]区间的最大值。

令g=log2(r-l+1)向下取整。则区间的最值就是max(dp[l][g],dp[r-2^g+1][g])

好的,我们开始对这些方程做一番分析。假设现在有5个数,为如下情况。这些分别是,dp[1][0],dp[2][0]....dp[5][0]

接着,我们可以统计到红色区域的最大值。这些分别是dp[1][1],dp[2][1]...dp[4][1]

最后,我们再统计到dp[1][2],dp[2][2],也就是1~1+4-1和2~2+4-1的最大值。

直到整个求完。(5后面的点因为皆为0,所以在取区间最大值的时候可以直接忽略)

有了这些后,如果要求l~r的最大值,我们需要让两个区间覆盖这个区间。假设我们询问1~5的最大值。

按道理来讲,我们假设2^x=5-1+1,然后dp[1][x]不就完事了?然而很可惜,x可能为小数。因此,x我们应当向下取整x',那么显然这样子取dp[1][x']会比dp[1][x]少一段。

于是我们再采用dp[5-2^x'+1][x']的方式来弥补。什么意思呢?

像这样,在两个互相被覆盖的区间里取一个最大值,是不是完美的解决了这个问题呢?而这个x就等于log2(x),x'即为log2(x)向下取整。

你可能会说这样有没有可能会没有全部覆盖,这很显然不可能。因为l+2^x'<r-2^x' 等价于 2^(x'+1)<r-l。而显然这个x'+1>=x,所以2^(x‘+1)>2^x=r-l+1>r-l。因此原不等式绝对不成立。

以上,ST表是一个很好的倍增思想入门。在LCA中也用到了与ST表非常类似的倍增思想。

ST表很简单。请注意常数,很容易就会了。Luogu P3865即为模板题。

下面是代码:

#include<bits/stdc++.h>
using namespace std;
template <typename T> T gn(T &x){
x=;
T plus=;
char ch=getchar();
while(ch<''||ch>'')plus=(ch=='-'?-:),ch=getchar();
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return x*plus;
}
const int N=1e5+;
int a[N][];
template <typename T> inline int mmax(T &a,T &b){return a<b?b:a;}
inline int dpow(int a,int x){
int ret=;
while(x){
if(x&)ret*=a;
a*=a;
x>>=;
}
return ret;
} int main(){
int n,m;
gn(n),gn(m);
for(int i=;i<=n;i++)
gn(a[i][]);
int plus=;
for(int j=;j<;j++){
for(int i=;i+plus<=n;i++)
a[i][j]=mmax(a[i][j-],a[i+plus][j-]);
plus*=;
}
int na,nb,x;
for(int i=;i<m;i++){
gn(na),gn(nb);
x=log2(nb-na+);
printf("%d\n",mmax(a[na][x],a[nb-dpow(,x)+][x]));
}
return ;
}

[模板]ST表浅析的更多相关文章

  1. [算法模板]ST表

    [算法模板]ST表 ST表和线段树一样,都能解决RMQ问题(范围最值查询-Range Minimum Query). 我们开一个数组数组\(f[maxn][maxn\log_2]\)来储存数据. 定义 ...

  2. 模板 ST表

    ST表 询问静态最值. code: #include <iostream> #include <cstdio> using namespace std; inline int ...

  3. 【模板】ST表

    给定一个长度为 \(N\) 的数列,和 \(M\) 次询问,求出每一次询问的区间\([l,r]\)内数字的最大值. 说明 对于30%的数据,满足: \(1 \leq N, M \leq 10 , 1≤ ...

  4. P3865 【模板】ST表

    P3865 [模板]ST表 https://www.luogu.org/problemnew/show/P3865 题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数 ...

  5. st表模板

    http://blog.csdn.net/insistgogo/article/details/9929103 这篇博客讲解的很详细了,求区间最大值也可以用st表,时间复杂度O(n log(n)),查 ...

  6. 【Luogu】P3865ST表模板(ST表)

    题目链接 本来准备自己yy一个倍增来着,然而一看要求O1查询就怂了. ST表模板.放上代码. #include<cstdio> #include<cstdlib> #inclu ...

  7. 洛谷 P3865 【模板】ST表

    P3865 [模板]ST表 题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每次查询复杂度为 O(1)O(1) 题目描述 给定一个长度为  ...

  8. 「LuoguP3865」 【模板】ST表 (线段树

    题目背景 这是一道ST表经典题——静态区间最大值 请注意最大数据时限只有0.8s,数据强度不低,请务必保证你的每次查询复杂度为 O(1) 题目描述 给定一个长度为 N 的数列,和 M 次询问,求出每一 ...

  9. 模板 - 数据结构 - ST表/SparseTable

    SparseTable,俗称ST表,其功能,就是静态的RMQ(区间最值查询)问题的解决.注意传入查询的时候两个参数的合法性,或者可以进行一次全部初始化来使得越界值不产生负面影响.不过访问越界是写程序的 ...

随机推荐

  1. 详解KMP算法【转】

    本文转载自:http://www.cnblogs.com/yjiyjige/p/3263858.html KMP算法应该是每一本<数据结构>书都会讲的,算是知名度最高的算法之一了,但很可惜 ...

  2. Codeforces Round #416 (Div. 2) C. Vladik and Memorable Trip

    http://codeforces.com/contest/811/problem/C 题意: 给出一行序列,现在要选出一些区间来(不必全部选完),但是相同的数必须出现在同一个区间中,也就是说该数要么 ...

  3. Codeforces Round #413, rated, Div. 1 + Div. 2 C. Fountains(贪心 or 树状数组)

    http://codeforces.com/contest/799/problem/C 题意: 有n做花园,有人有c个硬币,d个钻石 (2 ≤ n ≤ 100 000, 0 ≤ c, d ≤ 100  ...

  4. tp5.1 Env使用

    5.1版本取消了所有的系统常量,原来的系统路径变量改为使用Env类获取(需要引入think\facade\Env) echo "app_path=========".Env::ge ...

  5. QWebView_QWebEngineView

    1.http://stackoverflow.com/questions/29055475/qwebview-or-qwebengineview “ QWebView uses WebKit as t ...

  6. redis缓存穿透、缓存击穿、缓存雪崩

    缓存穿透 缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透. 解决办法: 预校验 在控 ...

  7. R语言绘制正太分布图,并进行正太分布检验

    正态分布 判断一样本所代表的背景总体与理论正态分布是否没有显著差异的检验.   方法一概率密度曲线比较法 看样本与正太分布概率密度曲线的拟合程度,R代码如下: #画样本概率密度图s-rnorm(100 ...

  8. 2019年,给JAVA程序员六个建议

    1.深入学习一项技能 或许你学习了很多各种高大上的框架与知识点,对其都了解一二,那么你的视野是很广的,但是这并不能很稳妥的为你的未来带来更好的提升,正如18年末的程序员寒季,大批程序员被辞,我想我们应 ...

  9. 利用Bomb打造自己的小程序

    小程序开发 Bomb免费后端云开发 首先,小程序的开发已是热门,一个前段技术人员必备的技术就是开发小程序.在这里推荐一个入门小程序文章(连胜出品). 对于小程序的入门开发就不再做详细介绍,这里针对Bm ...

  10. notepad++个人专注

    notepad++个人专注   快捷键 功能 1 Ctrl>>>>>>>>>>    Ctrl + b  匹配括号 Ctrl + d  选中 ...