ST表(倍增表)

介绍 st表 之前先看看 RMQ 问题是什么东西吧

RMQ

RMQ : Range Maximum/minimum Query

顾名思义,这就是指区间最大或最小值(区间最值)

ST表

ST表:Spars Table,一种可以解决 RMQ 的,基于 倍增 的数据结构


\(f[i][j]\) 表示从 \(i\) 开始连续 \(2^j\) 个数中的最值,如果 \(i\) 后面的数不足 \(2^j\) 个则全取

转移方程:

\[ f[i][j]=\left\{\begin{aligned} &min/max(f[i][j-1],f[i+2^{j-1}][j-1])& &,& &j>0,i+2^{j-1}\leq n&\\ &f[i][j-1]& &,& &j>0,i+2^{j-1}>n&\\ &a[i]& &,& &j=0& \end{aligned}\right.\]

  • \(f\) 数组可以递推得到

代码:

int x=log(n)/log(2);
for(int j=1;j<=x;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]);

时间复杂度: \(O(nlog(n))\)


询问方式:

询问区间为 \([l,r]\) ,设 \(x=\lfloor{log_2(l-r+1)}\rfloor\) ,则区间 \([l,l+2^x-1]\) 和 区间 \([r-2^x+1,r]\) 一定覆盖了 \([l,r]\) 这个区间内所有元素

所以答案为: \(min(f[l][x],f[r-2^x-1][x])\)

小优化:对于 \(1\) ~ \(n\) 每一个数先预处理 \(log(x)\) 下取整的结果,每次讯问时即为 \(O(1)\) 的复杂度

代码:

lg[0]=-1;
for(int i=1;i<=n;i++)    lg[i]=lg[i/2]+1;

for(int i=1;i<=m;i++){
    int le,r;
    scanf("%d%d",&le,&r);
    
    int x=r-le+1;
    printf("%d\n",max(f[le][lg[x]],f[r-(1<<lg[x])+1][lg[x]]));
}

几道练手题:

  1. 模板题
  2. 另一道模板题 (貌似树状数组和线段树也能做)

需要思考一下的题:

  1. 序列
  2. Foutain
posted @ 2022-02-15 14:41  _yolanda  阅读(157)  评论(0编辑  收藏  举报