首页 > 其他 > 详细

ST表

时间:2018-10-06 16:18:54      阅读:120      评论:0      收藏:0      [点我收藏+]

ST表是一个用来解决去间最值(RMQ)问题的算法。预处理时间复杂度为O(nlogn),查询复杂度为O(1)。这是一个离线算法,不支持在线修改。

这里洛谷模板为例题讲解,洛谷原题链接:https://www.luogu.org/problemnew/show/P3865

用f[i][j]表示[i,i+2^(j)-1](长度为2^j)这个区间里的最大值。那么如何维护呢?我们可以用二分的思想,[i,i+2^(j)-1]区间的最大值可以由[i,i+2^(j-1)-1]的最大值和[i+2^(j-1)-1,i+2^(j)-1]的最大值得来,所以f[i][j]=max(f[i][j-1],f[i+2^(j-1)-1][j-1])。处理完成之后又要怎么样查询呢?我们可以很容易的想到,当区间长度是2^n的时候,我们可以直接输出。但如果不是的话呢?我们可以画一张图来理解一下:

技术分享图片

我们可以算出比区间长度小的最大的2^x,然后通过l往后和从r往前两段区间,求出[l,r]的最大值,那么max[l,r]=max(st[l][x],st[r-(1<<x)+1][x])。

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,x,y,st[100100][20];
int er[100100];
int main(){
    register int i,j;
    scanf("%d%d",&n,&m);
    for(i=1;(1<<i)<=n;++i) er[(1<<i)]=i;
    for(i=3;i<=n;++i) if(!er[i]) er[i]=er[i-1];
    for(i=1;i<=n;++i) scanf("%d",&st[i][0]);
    for(j=1;(1<<j)<=n;++j)
      for(i=1;i+(1<<(j-1))<=n;++i)
        st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
    for(i=1;i<=m;++i){
        scanf("%d%d",&x,&y);
        int z=er[y-x+1];
        printf("%d\n",max(st[x][z],st[y-(1<<z)+1][z]));
    }
    return 0;
}

ST表

原文:https://www.cnblogs.com/Glacier-elk/p/9747470.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!