RMQ问题

题目:忠诚

解题思路

代码里有

代码

#include 
#include //cmath库下有log()和log2()等
#include //algorithm用来做max(),min()
using namespace std;
int a[100010];
int dp[100010][30];//dp[i][j]表示从i 开始到i+2^j-1区域间最小值
int main(){
    int m,n;
    cin>>m>>n;
    for(int i=1;i<=m;i++){
        cin>>dp[i][0];
    }
    for(int j=1;j<=log2(m);j++){//次数最多是log2(m)    之所以2^j在先是因为j是个数,先把两个两个的最小值求完才能求三个三个以此类推
        for (int i=1;i<=m+1-(1<<j);i++){//之所以是 m+1-2^j  是因为如果从1到m再加上2^j的个数可能会超
            dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);//这个区间内最小值就是它左半部分的最小值与右半部分的最小值相比所得出的最小值
        }
    }
    for(int i=0;i<n;i++){
        int l,r,len,k;
        cin>>l>>r;
        len=r-l+1;
        k=log2(len);
        cout<<min(dp[l][k],dp[r-(1<<k)+1][k])<<" ";//两者组合可以用在所有区间里,不信可以手动试试
    }
    return 0;
}


其实不长,就是一个预处理的思想

你可能感兴趣的:(提高组,noip,RMQ,C++,noip,提高组)