• RMQ ST表 静态区间最大值


    RMQ(Range Minimum/Maximum Query)

    作用:在一个给定的序列A中求区间 [ x , y ] 的最值

      设序列长度为n,有m次询问

    优点:预处理O(nlogn),询问O(1),总复杂度为O(nlogn+m),与线段树和树状数组相比而言,RMQ在处理询问次数多的情况下有绝对优势

    思想:递推/动态规划/倍增

    预处理:

      首先我们预处理出数组 f [ i ] [ j ] ,代表从第 i 位开始的 2j 位的最大值,即 [ i , i + 2j -1 ]

      f [ 1 ] [ 1 ] 表示从 1~2f [ 2 ] [ 3 ]表示从 2~9

      那么将 j 作为阶段 ,[ i , i + 2j -1 ] 可以由 [ i , i + 2j-1 - 1] [ i + 2j-1 , i + 2j - 1] 两个区间得到

      可以表示为如下的递推式。

    f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);

      因为是 f [ i ] [ j ] 从 j - 1 得来,所以将 j 设为阶段,套在外层循环

      其中第一个 for 的范围根据题目范围设定 , 本模板的数据范围参考 [洛谷 P3865 【模板】ST表]

    for(int j=1;j<=21;++j)
            for(int i=1;i+(1<<j)-1<=n;++i)
                f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);

      考虑到 f [ i ] [ 0 ] 为第 i 位 本身的数,所以可以将原序列的数读入到 f [ i ] [ 0 ]中

    查问:

           把 [ x , y ] 区间的长度记为 len = y - x + 1 , 记 k=log2(len)

      那么[ x , y ] 区间的最大值为区间 [ x , x + 2k - 1] 和 [ y - 2k +1 , y] 的最大值,可得如下

    int query(int x,int y){
        int k=log2(y-x+1);
        return max(f[x][k],f[y-(1<<k)+1][k]);
    }

      我们知道 log2 是向下取整 因此 保证以上两个小区间不超大区间的范围

      因为一个小区间是从左边头开始,一个小区间是从右边头开始,小区间长度相等,小区间长度记为len2,即使log2 向下取整,两小区间仍重叠,

      即 len2 = 2log2(len) ,log2  向下取整, 2log2(len) > len/2  即 2*len2>len  

      那么就可以保证query函数的正确性了

    贴一下代码,模板题是[洛谷 P3865 【模板】ST表]

    #include<bits/stdc++.h>
    #define maxn 100010
    using namespace std;
    
    int f[maxn][22],n,m;
    
    int query(int x,int y){
        int k=log2(y-x+1);
        return max(f[x][k],f[y-(1<<k)+1][k]);
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i) scanf("%d",&f[i][0]);
        for(int j=1;j<=21;++j)
            for(int i=1;i+(1<<j)-1<=n;++i)
                f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
        for(int i=1;i<=m;++i){
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%d
    ",query(x,y));
        }
    }

      还有,这是绝对AC不了的,因为没加快读,会TLE的

  • 相关阅读:
    mount命令详解
    traceroute命令详解
    etcd节点扩容至两个节点
    shell历史命令
    etcd单节点安装
    linux中修改环境变量及生效方法
    ansible最佳实战部署nginx
    用roles部署nginx
    playbook部署mangodb
    安装mangodb
  • 原文地址:https://www.cnblogs.com/lamkip/p/13271552.html
Copyright © 2020-2023  润新知