区间最值的优秀数据结构---ST表

ST表,听起来高大上,实际上限制非常多,仅仅可以求最值问题;

为什么?先从原理看起;

st表运用了倍增的思想:st[i][j] = min(st[i][j - 1],st[i + 2^(j - 1))][j - 1]);

意义是:从i开始向后连续2^j个位置的最大值是,i开始向后连续2^(j-1)个位置的最大值和i+2^(j-1)开始向后连续2^(j-1)个位置的最大值;

好了,结构建立起来了,那么怎么查询呢?

一个公式:2^log(a)>a/2 。

所以说,查询(x,y)时我们设k=log(y-x+1);

ans=max(f[x][k],f[y-(1<

现在我们知道了,ST表只能求最值的原因是它在查询时,为了节约时间复杂度而导致查询区间取并集操作;这样求区间和便无法得到正确答案;

附:1.求一维ST最值:

 

#include 
#define int long long
using namespace std;
int a[100010];
int f[100010][40],g[100010][40];
int n,q;
void build()
{
	for(register int i=1;i<=n;i++){
		f[i][0]=a[i];
		g[i][0]=a[i];
	}
	for(register int j=1;(1<

 

 

而二维st表原理就是将一个正方形分成了4份:

令 st[i][j][k]表示左上角为i,j,边长为k的正方形中的最大值。
st[i][j][k]=Max(st[i][j][k-1],st[i+(1<

查询时与一维ST表类似,取并集操作;

#include 
#define inc(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;
int a,b,n;
int mmap[1001][1001];
int f[1001][1001][8],g[1010][1010][8];
void build()
{
	inc(i,1,a){
		inc(j,1,b){
			f[i][j][0]=mmap[i][j];
			g[i][j][0]=mmap[i][j];
		}
	}
	for(int k=1;k<=7;k++){
		for(int i=1;i+(1<

 在做一维和二维ST表的时候,我们可以自己推出:三维的ST表,甚至于四维的ST表;只不过由于他们的时间复杂度较高,内存需求较大,我们便不再需要他们了。但这种思维可以运用到别的地方。

 

转载于:https://www.cnblogs.com/kamimxr/p/11608543.html

你可能感兴趣的:(区间最值的优秀数据结构---ST表)