洛谷P3865【模板】ST表 ST表

网址:https://www.luogu.org/problem/P3865

题意:

静态区间最大值,且需要在$O(nlgn)$预处理,$O(1)$查询。

题解:

建立ST表,ST表是一种基于倍增的用于快速查询区间最值的数据结构,它由一个大小为$O(nlgn)$的二维数组构成,用$st[i][j]$表示从$j$到$j+2^{i-1}$的最值,$j$到$j+2^{i-1}$的长度为$2^i$,那么一半的长度就等于$2^{i-1}$,那么前半段的状态表示为$st[i-1][j]$。后半段的长度也为$2^{i-1}$,起始位置为$j+2^{i-1}$。那么后半段的状态表示为$st[i-1][j+2^{i-1}]$。所以:$st[i][j]=ope(st[i-1][j],st[i-1][j+2^{i-1}])$。

然后是查询:我们了解如下定理:$2^{log(a)+1}>a$,那么我们要查询$l$到$r$的最值。设$len=r-l+1,t=log(len)$,根据上面的定理:$2^t>len/2$,所以从位置上来说,$l+2^t$越过了$l$到$r$的中间!因为位置过了一半,所以$l$到$r$的最值可以表示为$ope$(从$l$往后$2^t$的最值,从$r$往前$2^t$的最值),前面的状态表示为$st[t][l]$。设后面(从$r$往前$2^t$的最值)的初始位置是$k$,那么$k+2^t-1=r$,所以$k=r-2^t+1$,所以后面的状态表示为$st[t][r-2^t+1]$,所以$l$到$r$的最小值表示为$ope(st[t][l],st[t][r-2^t+1])$,所以查询时间复杂度是$O(1)$。(参考博客:https://blog.csdn.net/Hanks_o/article/detail/77547380)

AC代码:

#include 
#include 
#include 
int num[1000005];
int st[25][1000005];//长度为i起始位置为j的最小值
#define max(a,b) (a>b?a:b)
using namespace std;
void init(int n)
{
    for(int i=1;i<=n;++i)
        scanf("%d",&num[i]);
    for(int i=1;i<=n;++i)
        st[0][i]=num[i];
    for(int i=1;(1<

 

转载于:https://www.cnblogs.com/Aya-Uchida/p/11325263.html

你可能感兴趣的:(洛谷P3865【模板】ST表 ST表)