zoukankan      html  css  js  c++  java
  • ST表

    ST表通常用于解决RMQ问题,支持的事静态查询区间的最值,不可修改。

    其中建表的时间复杂度是O(nlgn),查询则是O(1)。

    这里ST表其实用到了动态规划以及而分的思想,把每一个区间二分至自己是区间的最值,然后逐步进行比较,然后进行查询即可。首先我们建立一个st[][],用来存储从第i个开始,往后2^j个数的最大值。在这之前,我们要进行一个对数运算(当然还要明白位运算,1<<j等同于2^j),把以二为底i的对数求出来,方便下面计算长度。然后就去写函数,推出f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);

    表示i 到 2^(j-1)-1与 i+2^(j-1)到i+2^j的最大值。最后进行查询的时候,我们不能直接输出st[l][r],所以我们要先求出2的k次方等于r-l+1,然后分别求出i,i+2^k和r-i^k,r的最大值,这样就可以保证都访问过了,重复也无关于求最值。

    代码

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define M 25
     5 #define N 100005
     6 using namespace std;
     7 int n,m;
     8 int a[N],Log[N];
     9 int f[N][M];
    10 int l,r;
    11 void GetLog()
    12 {
    13     Log[1]=0;
    14     for(int i=2;i<=n+1;i++)
    15       Log[i]=Log[i/2]+1;
    16 }
    17 void RMQ()
    18 {
    19     for(int i=1;i<=n;i++)
    20       f[i][0]=a[i];
    21     for(int j=1;(1<<j)<=n;j++){
    22       for(int i=1;i+(1<<(j-1))<=n;i++){
    23           //[i,i+2^{j-1}-1] & [i+2^{j-1},i+2^{j} -1]
    24         f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    25         }
    26     }
    27 }
    28 int k,ans;
    29 int main()
    30 {
    31     scanf("%d%d",&n,&m);
    32     for(int i=1;i<=n;++i)
    33       scanf("%d",&a[i]);
    34     GetLog();
    35     RMQ();
    36     for(int i=1;i<=m;++i)
    37     {
    38         scanf("%d%d",&l,&r);
    39         int k=Log[r-l+1];
    40         ans=max(f[l][k],f[r-(1<<k)+1][k]);
    41         printf("%d
    ",ans);
    42     }
    43     return 0;
    44 }
  • 相关阅读:
    XML 浏览器支持
    浏览器中的XML
    C/C++中判断某一文件或目录是否存在
    C/C++程序员必须熟练应用的开源项目 -- 转
    VC 中窗口的销毁
    sql proc触发异常处理回滚
    为Array 添加indexOf
    Js的两种post方式
    sql 针对多个id或名称的分割和组合
    sql 查看语句的性能
  • 原文地址:https://www.cnblogs.com/china-mjr/p/11618359.html
Copyright © 2011-2022 走看看