• 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 }
  • 相关阅读:
    Tiny_4412的NFS挂载
    tiny4412学习一:编译uboot,体验裸机
    开通博客,记录历程,开启新的征程
    mysql 多表联合做运算(求俩点的距离)
    golang gin框架使用图形验证码
    js rgb和16进制相互转换
    [转载] Centos7的安装、Docker1.12.3的安装,以及Docker Swarm集群的简单实例
    openstack golang sdk使用
    sendcloud golang 发送短信 示例代码
    Harbor配置https,并安装内容信任插件(notary)
  • 原文地址:https://www.cnblogs.com/china-mjr/p/11618359.html
Copyright © 2020-2023  润新知