//点击后出现烟花效果

ST表

ST表(Sparse Table 稀疏表)


用处:


可以用来解决RMQ(区间最值)等可重复贡献问题


引入:


对于RMQ问题,我们通常有这几种方法处理:

  1. 朴素(即搜索)O(nm)

  2. 打表 O(n2)

  3. ST表 O(nlogn)

  4. 线段树 O(nlogn)

我们比较容易想到用打表的方法,也就是比较简单的dp,像这样:
定义 ans[i][j] 表示区间 [i,j] 的最值

{ans[i][j]=a[i],i=jans[i][j]=max(ans[i][j1],a[j])

可是这样的空间复杂度 O(n2) 时间复杂度 O(n2) 不是很令人满意,所以我们考虑用ST表来处理静态(offline)的RMQ问题。


分析:


要求解一个区间的最值,ST表用了类似区间dp的方法。
dp[i][j] 表示的是从 i 开始,长度为 2j 的区间中的最值。也就是区间 [i,2j+i1] 的最值。

对于每一次询问,我们可以通过 lr 算得区间的长度 len ,然后计算 j=log2len 最大值就是 max(dp[l][j],dp[r2j+1][j])
就像这样:

就是在这两段有重叠部分的区间取其中的最大值,重叠并不会影响 [l,r] 区间的最大值。


预处理:


首先,当区间长度为0时,区间的最值就是区间端点的值。即 dp[i][0]=a[i]

然后开始类似区间dp的处理方法。

先枚举区间长度,再枚举区间端点。

dp[i][j]=max(dp[i][j1],dp[i+2j1][j1])

这里的 j1 相当于将区间对半分,整个的最值等于左边和右边取最值。
代码:

for (int j = 1; j <= log2(n); j++)
    for (int i = 0; i + (1 << j) - 1 < n; i++)
        dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);



查询:


和分析中说的一样
代码:

int query(int l, int r)
{
    int j = (int)log2(r - l + 1);
    return max(dp[l][j], dp[r - (1 << j) + 1][j]);
}




例题

模板代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
const int log2N = 17; //这是计算得到的log2(N)
int dp[N][log2N]; //dp[i][j] 表示左端点为 i 区间长度为 2^j 的区间中的最大值,即区间[i,i+2^j-1]
int query(int l, int r)
{
    int t = r - l + 1;
    int j = (int)log2(t);
    return max(dp[l][j], dp[r - (1 << j) + 1][j]);
}
int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) scanf("%d", &dp[i][0]);
    for (int j = 1; j <= log2(n); j++)
        for (int i = 0; i + (1 << j) - 1 < n; i++)
            dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);

    int l, r;
    while (m--)
    {
        scanf("%d%d", &l, &r);
        printf("%d\n", query(l - 1, r - 1));
    }
}

  1. 可重复贡献问题

    我们要查询一块区域 A 内的元素性质, 可以将该区域 用两块区域 B C 来替代(这两个区域, 可以包含相同元素,但不可以 包含不属于 A 的元素) 即: BC=A,BCA
    通过这个两个子区域的值, 可以推出 A 的值。

    换句话说, 假如我们要求的值 函数为: F(S) (表示 S 这个集合里所有元素的结果)那么必须要满足: F(a,b,c,d)=F(F(a,b,c),F(b,c,d))

    比如:RMQ 问题、区间 GCD 、区间&操作、区间|操作等。 ↩︎

posted @   JunieXD  阅读(66)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示