zoukankan      html  css  js  c++  java
  • RMQ ST算法

    【算法概述】

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

    定义:f[i][j]表示i到i+2^j-1这段区间的最大值。

    预处理:f[i][0]=a[i]。即i到i区间的最大值就是a[i]。

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

    两段的长度均为2^j-1。f[i][j]的最大值即这两段的最大值中的最大值。

    得到f[i][j]=max(f[i][j-1],f[i+2^(j-1)][j-1])。

    【模板】

    //poj 3264
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    
    #define MAXN 50010
    #define Max(x,y) (x>y?x:y)
    #define Min(x,y) (x>y?y:x)
    
    int maxsum[MAXN][20],minsum[MAXN][20];//表示从第i个数起连续2^j个数中的最大值/最小值
    
    void RMQ(int num)
    {
        for(int j=1;j<20;j++)
            for(int i=1;i<=num;i++)
            {
                if(i+(1<<j)-1 <= num)
                {
                    maxsum[i][j]=Max(maxsum[i][j-1],maxsum[i+(1<<(j-1))][j-1]);
                    minsum[i][j]=Min(minsum[i][j-1],minsum[i+(1<<(j-1))][j-1]);
                }
            }
    }
    
    int main()
    {
        int i,j,num,t,query;
        while(scanf("%d%d",&num,&query) != EOF)
        {
            for(i=1;i<=num;i++)
            {
                scanf("%d",&maxsum[i][0]);
                minsum[i][0]=maxsum[i][0];
            }
            RMQ(num);
            int st,en,maxl,minl;
            while(query--)
            {
                scanf("%d%d",&st,&en);
                int k=(int)((log(en-st+1))/log(2.0));
                maxl=Max(maxsum[st][k],maxsum[en-(1<<k)+1][k]);
                minl=Min(minsum[st][k],minsum[en-(1<<k)+1][k]);
                printf("%d
    ",maxl-minl);
            }
        }
        return 0;
    }
  • 相关阅读:
    空心杯 电机
    scikit learn 安装
    python fromkeys() 创建字典
    python 清空列表
    mac最常用快捷键
    php while循环
    php 获取某个日期n天之后的日期
    php 添加时间戳
    php 格式化时间
    php 数值数组遍历
  • 原文地址:https://www.cnblogs.com/czsharecode/p/9705318.html
Copyright © 2011-2022 走看看