zoukankan      html  css  js  c++  java
  • RMQ-ST

    RMQ(Range Minimum/Maximum Query)问题,即区间最值查询问题,ST表可以在O(nlog(n))的预处理下将查询做到O(1)

    1.预处理出f[i][j]——从i到i+(1<<j)-1这个区间中的最值

    inline void ST(){
        int m=log(n)/log(2.0);
        for(int i=0;i<m;i++){
            for(int j=1;j+(1<<(i+1))-1<=n;j++){
                f[j][i+1]=min(f[j][i],f[j+(1<<i)][i]);
            }
        }
    }

     2.对于每个查询区间[l,r]
    找到一个k使[l,l+(1<<k)-1]和[r-(1<<k),r]两个区间能完全覆盖[l,r]这个区间,O(1)查找这两个区间再求最值即可,k即为log(r-l+1)

    inline int query(int l,int r){
        int k=log(r-l+1)/log(2.0);
        return min(f[l][k],f[r-(1<<k)+1][k]);
    }

     例题

    http://hihocoder.com/problemset/problem/1068

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define maxn 1000005
    int f[maxn][20],n,q;
    inline int query(int l,int r){
        int k=log(r-l+1)/log(2.0);
        return min(f[l][k],f[r-(1<<k)+1][k]);
    }
    inline void ST(){
        int m=log(n)/log(2.0);
        for(int i=0;i<m;i++){
            for(int j=1;j+(1<<(i+1))-1<=n;j++){
                f[j][i+1]=min(f[j][i],f[j+(1<<i)][i]);
            }
        }
    }
    int main(){
        int l,r;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",f[i]);
        ST();
        scanf("%d",&q);
        for(int i=0;i<q;i++)scanf("%d%d",&l,&r),printf("%d
    ",query(l,r));
        return 0;
    }
  • 相关阅读:
    冒泡排序
    选择排序
    算法分析(54页)
    算法设计分析(44页)
    算法设计分析(44页)
    数据结构——算法设计(12页)方案三
    数据结构——算法设计(12页)方案三
    区间dp
    区间dp
    动态规划的进一步理解
  • 原文地址:https://www.cnblogs.com/bennettz/p/7841242.html
Copyright © 2011-2022 走看看