zoukankan      html  css  js  c++  java
  • RMQ与st表

    模板题
    P3865 【模板】ST表

    代码

    实质也是DP,利用倍增获取从i开始长度为(2^0,2^1,2^2…2^j)的区间内的最大值。
    这样对于任意区间([l,r])都有,令(dis=r-1+1)则有(k_0=2^c,2^{k_0}≤dis≤2^{k_0+1})这样在区间([l,l+k0-1],[r-k0+1,r])完全覆盖了这个区域(中间可能有重叠)

    #include <iostream>
    #include <cmath>
    #include <cstdio>
    using namespace std;
    int dp[100100][20];
    int a[100100];
    int lg[100100];
    int n,m;
    void st(){
        for(int i=1;i<=n;i++){
            dp[i][0]=a[i];
        }
        for(int j=1;(1<<j)<=n;j++){
            for(int i=1;i+(1<<j)-1<=n;i++){
                dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
            }
        }
    // 方法2
    //    int k=0;
    //    for(int i=1;i<=n;i++){
    //        if(i<=(1<<(k))){
    //            lg[i]=k;
    //        }else{
    //            k++;
    //            lg[i]=k;
    //        }
    //    }
    }
    int RMQ(int l,int r){
        int k=0;
    //  方法2
    //	k=lg[r-l+1]-1;
    
    //  方法3
    //    while((1<<(k+1))<=r-l+1){
    //		k++;
    //	}
    
    //  方法1
        k=(double)log(r-l+1)/log(2);
        return max(dp[l][k],dp[r-(1<<k)+1][k]);
    }
    void init(){
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
    }
    int main(){
        init();
        st();
        // cout<<RMQ(1,5);
        int q,w;
        for(int i=1;i<=m;i++){
            scanf("%d%d",&q,&w); 
            printf("%d
    ",RMQ(q,w)); 
        }
    }
    

    计算log的方法可以提前用O(n)的预处理(方法2)或者每次lgn的计算(常数很小,基本上可以忽略)或者不知道常数的。。log算法
    反正从代码上来看时间,log(<)预处理(<)(O(lgn))计算
    分别是1112ms 1224ms 1648ms
    洛谷评测

  • 相关阅读:
    zoj 1239 Hanoi Tower Troubles Again!
    zoj 1221 Risk
    uva 10192 Vacation
    uva 10066 The Twin Towers
    uva 531 Compromise
    uva 103 Stacking Boxes
    稳定婚姻模型
    Ants UVA
    Golden Tiger Claw UVA
    关于upper、lower bound 的探讨
  • 原文地址:https://www.cnblogs.com/zhshh/p/rmqst.html
Copyright © 2011-2022 走看看