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;
    }
  • 相关阅读:
    awk查看本机IP+查看本网段mac
    wget
    kvm安装,使用,优化
    方向
    bindview+dlz(mysql)
    页面侧滑栏效果
    数据库的事务理解
    页面平衡移动进出的效果
    返回键弹出是否退出对话框
    引导页之页面等待3秒跳转
  • 原文地址:https://www.cnblogs.com/bennettz/p/7841242.html
Copyright © 2011-2022 走看看