zoukankan      html  css  js  c++  java
  • 【知识点】RMQ问题的ST表实现

    $RMQ$问题:给定一个长度为$N$的区间,$M$个询问,每次询问$[L_i,R_i]$这段区间元素的最大值/最小值。

    $RMQ$的高级写法一般有两种,即为线段树和$ST$表。

    本文主要讲解一下$ST$表的写法。(以区间最大值为例)

    $ST$表:一种利用$dp$思想求解区间最值的倍增算法。

    定义:$f(i,j)$表示$[i,i+2^{j}-1]$这段长度为$2^{j}$的区间中的最大值。

    预处理:$f(i,0)=a_i$。即$[i,i]$区间的最大值就是$a_i$。

    状态转移:将$[i,j]$平均分成两段,一段为$[i,i+2^{j-1}-1]$,另一段为$[i+2^{j-1},i+2^{j}-1]$。

    两段的长度均为$2^{j-1}$。$f(i,j)$的最大值即这两段的最大值中的最大值。

    得到$f(i,j)=max{f(i,j-1),f(i+2^{j-1},j-1)}$。

    void RMQ(int N){
        /*注意外部循环从j开始,
        因为初始状态为f[i][0],
        以i为外层会有一些状态遍历不到。*/ 
        for(int j=1;j<=20;j++)  
            for(int i=1;i<=N;i++)
                if(i+(1<<j)-1<=N)
                    f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    }

    查询:若需要查询的区间为$[i,j]$,则需要找到两个覆盖这个闭区间的最小幂区间。

    这两个区间可以重复,因为两个区间是否相交对区间最值没有影响。(如下图)

    当然求区间和就肯定不行了。这也就是$RMQ$的限制性。

    因为区间的长度为$j-i+1$,所以可以取$k=log_2(j-i+1)$。

    则$RMQ(A,i,j)=max{f(i,k),f(j-2^{k}+1,k)}$。

    代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int a[100001],f[100001][20];
    inline int read(){
        int x=0,f=1;
        char c=getchar();
        for(;!isdigit(c);c=getchar())
            if(c=='-')
                f=-1;
        for(;isdigit(c);c=getchar())
            x=x*10+c-'0';
        return x*f;
    }
    void RMQ(int N){
        for(int j=1;j<=20;j++)    
            for(int i=1;i<=N;i++)
                if(i+(1<<j)-1<=N)
                    f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]); 
    }
    int main(){
        int N=read(),M=read();
        for(int i=1;i<=N;i++) a[i]=read();
        for(int i=1;i<=N;i++) f[i][0]=a[i];
        RMQ(N); 
        while(M--){
            int i=read(),j=read();
             int k=(int)(log((double)(j-i+1))/log(2.0)); 
            printf("%d
    ",max(f[i][k],f[j-(1<<k)+1][k]));
        }
        return 0;
    }
  • 相关阅读:
    css的选择器
    javaScript 的变量使用
    关于外键约束
    javaScript中运算符
    css介绍和三种引入方式
    关于盒子模型
    类和类的六种关系
    DQL和DML更多操作
    javaScript的特点
    关于 让页面中的按钮 响应回车
  • 原文地址:https://www.cnblogs.com/YSFAC/p/7189571.html
Copyright © 2011-2022 走看看