UOJ Logo qx的博客

博客

数据结构

2023-11-30 18:15:16 By qx

$$ \mathcal{ST}$$

像某个 $Cbh$ 一样 $st$ 表都不会写还是不好的。所以写一篇 $st$ 表。

$ST$ 表支持维护区间问题,并且要求静态。可以达到预处理 $O(n\log n)$,而单词查询 $O(1)$ 的恐怖效率。空间复杂度 $O(n\log n)$ ,想比于线段树其应用范围稍显狭窄。

$\mathcal{But...}$ $\mathcal{ST}$ 的单词查询是 $O(1)$ 的。

下面主要以 $\min$ 操作为例介绍

$\mathcal{ST}$ 的思想主要基于倍增。

先要 $Init(log2)$ 当然如果你不嫌弃 $C++$ 的大常数 $\log_2$ 的话也不是不行。

只需要 $Init([1-n])$ 的 $\log_2$ 就好了。这一步主要是为了应付后面倍增要求。显然,$\log_2(x)=log_2(\left[\frac{x}{2}\right])+1$ 理由不想多说。按照这个步骤初始化即可。

$$\mathcal{STEP . 1}$$

然后就是预处理。可以得到一个 $\min$ 特有的关系式,大概就是这个相貌:

$$\min_{i=l} ^r a[i] = \min\{\min _{i=l} ^{k\leq r} a[i],\min_{k\geq l} ^r a[i]\}$$

等式右边的两项可以通过刚刚的方法求得。

这样就可以开始推导推导了:设 $dp[i][j]$ 表示 $\min _{k=l} ^{l+2^j} a[k]$,这里就可以出来一个转移方程:

$$dp[i][j]=\min\{dp[i][j-1],dp[i+2^{j-1}][j-1]\}$$

理由如上。

$$\mathcal{STEP.2}$$

查询操作。

$$\min_{i=l} ^r a[i] = \min\{dp[l][k],dp[r-2^k][k]\}$$

其中 $k=\log_2(r-l+1)$

理由还是如上。

$$\mathcal{STEP.3}$$

吸取了某个叫 $\mathcal{CBH}$ 同学的教训,我们可以知道 $k$ 就是 $k$ ,不要 $k-1.$

上代码。

// here is Init
void init(){
    lg[0]=-1;
    FOR(i,1,n) lg[i]=lg[i>>1]+1;
    FOR(i,1,n) dp[i][0]=a[i];
    int lim=lg[n];
    FOR(k,1,lim)
        FOR(s,1,n+1-(1<<k))
            dp[s][k]=max(dp[s][k-1],dp[s+(1<<(k-1))][k-1]);
}
// here is Query
l=read();r=read();
int k=lg[r-l+1];
cout<<max(dp[l][k],dp[r-(1<<k)+1][k])<<'\n';

那么除了 $\min$ 之外 $\mathcal{ST}$ 还可以维护 $\mathcal{GCD,MAX,OR,LCM}$ 之类的东西。

$$\mathcal{O(n\log n)+O(n \log n)+O(1)}$$

评论

qx
什么个鬼?

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。