st 表的学习总结
posted on 2023-05-10 05:38:53 | under 笔记 | source
基础概念
需以 \(O(nlogn)\) 的时间复杂度构造 st 表。
可以用 \(O(1)\) 的时间复杂度,查询区间最大、最小值。但广义地说,满足结合律即可,如 \(gcd\)、异或等。
但 \(st\) 表是静态的,难以再修改。
st 表 vs 线段树
\(st\) 表的优势是:代码量短、实现容易,查询时间较短。
线段树的优势是:可以动态修改。
实现
首先,\(st\) 表是用动态规划实现的,用到了倍增的思想。
定义 \(st[i][j]\) 表示:一段以 \(i\) 为起点,长度为 \(2^j\) 的区间的最值。
容易推出转移方程:\(st[i][j]=max(st[i][j-1],st[i+2^{j-1}][j-1])\) 。
怎么查询?不妨设 \(len=log2(r-l+1)\),向下取整,用两段长为 \(len\) 区间覆盖即可:\(max(st[l][len],st[r-2^{len}+1][len])\)。
代码
#include<bits/stdc++.h>
using namespace std;
int n,m,a[100005],d[100005],l,r,len,f[100005][30];
void st()
{
for(int j=0; j<=25;j++)
for(int i=1; i+(1<<j)-1<=n;i++)
{
if(j==0) f[i][j]=a[i];
else f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);
}
}
int main(){
cin>>n>>m;
for(int i=1; i<=n;i++)
{
scanf("%d",&a[i]);
if(i>=2) d[i]=d[i>>1]+1;
}
st();
for(int i=1; i<=m;i++)
{
scanf("%d%d",&l,&r);
len=d[r-l+1];
printf("%d\n",max(f[l][len],f[r-(1<<len)+1][len]));
}
return 0;
}
几道好题
P1198 [JSOI2008] 最大数
一开始看到:这不是单调队列模板吗?
后来由空线段树的思想,联想到边读边建表,过了。
P7244 章节划分
很好的一道题。
首先想到:答案一定是最大数的因子。
于是可以对最大数进行分解质因数,枚举每个因子:把它作为答案是否可行?就转化为了判定问题。
可求出在满足条件的情况下,区间最多被分为几段。因为,假如最多分为 \(k\) 段,那么可以把其中两段合在一起,变为 \(k-1\) 段,还是满足条件,以此类推。
下面给出一种巧妙的递归写法:
要求 \((l,r)\) 这段区间至多可被为多少段,不妨设 \(ma\) 为区间最大值。
那么可分为两种情况:
-
\(ma\) 整除答案,那为了使段数最多,不妨把 \(ma\) 独立出来,则:\((l,r)=(l,ma-1)+(ma+1,r)+1\) 。
-
不整除,考虑把 \(ma\) 纳入它上面一级的区间,因为上一级一定满足条件。因此:若 \(l>1\),不用考虑 \(l\) 到 \(ma\) 这段区间 (\(l<1\) 的话没法覆盖住 \(ma\))。若 \(r<n\),同理。
P7009 [CERC2013] Magical GCD
显而易见,\(st\) 表可求出区间 \(gcd\) 的值。
上手枚举下 \(gcd\) 的值,可发现:一段区间,左端点固定,\(gcd\) 的值随着右端点右移而单调不增。
由于题目时限为 \(8s\),很容易想出一种暴枚的做法。
固定区间左端点,用二分求出 \(gcd\) 值相等时,右端点最远在哪,然后统计最大值即可。
P2048 [NOI2010] 超级钢琴
题目要求 \(k\) 段序列最大值,贪心地想,就是求 \(k\) 次最大值。
那不妨固定住区间左端点 \(i\),对于每个 \(1≤i≤n\),都能找到使该区间和最大的 \(j\),把它们存入堆。我用的是优先队列 + 重载运算符的做法,因为相对简单。
然后要用到前缀和,每个区间可表示为 \(s[j]-s[i]\) 的形式,既然要求最大且已知 \(s[i]\) 的值,那么只需找到最大的 \(s[j]\),可以用 \(st\) 表预处理。
接着循环 \(k\) 次,每次取最大的区间,把它拆分为次小区间(最多 \(2\) 个),因为之后可能取到它们。
那么如何拆分?设 \(l\)、\(r\) 分别最大区间左右端点,我们已知 \(ma\) 的值,使得 \(s[ma]-s[i]\) 的值最大,因此次大 \(m_1\) 一定在 \(l\) 到 \(ma-1\) 之间;当然,前提是 \(l<ma\)。\(m_2\) 同理。

浙公网安备 33010602011771号