zoukankan      html  css  js  c++  java
  • ST表

    ST算法(Sparse Table):       

     它是一种动态规划的方法。以最小值为例。a为所寻找的数组,用一个二维数组
        f(i,j)记录区间[i,i+2^j-1]区间中的最小值。其中f[i,0] = a[i];所以,对于任意
     的一组(i,j),f(i,j) = min{f(i,j-1),f(i+2^(j-1),j-1)}来使用动态规划计算出来。
         这个算法的高明之处不是在于这个动态规划的建立,而是它的查询:它的查询效
     率是O(1)!如果不细想的话,怎么弄也是不会想到有O(1)的算法的。假设我们要求
     区间[m,n]中a的最小值,找到一个数k使得2^k<n-m+1,即k=[ln(b-a+1)/ln(2)] 这样,
     可以把这个区间分成两个部分:[m,m+2^k-1]和[n-2^k+1,n]!我们发现,这两个区间
     是已经初始化好的!前面的区间是f(m,k),后面的区间是f(n-2^k+1,k)!这样,只要
     看这两个区间的最小值,就可以知道整个区间的最小值!

    小结:   

     稀疏表(SparseTable)算法是O(nlogn)-O(1)的,对于查询很多大的情况下比较好。    

     ST算法预处理:用dp[i,j]表示从i开始的,长度为2^j 的区间的RMQ,则有递推式dp[i,j]=min{dp[i,j-1],dp[i+2j-1,j-1]}即用两个相邻的长度为2j-1的块,更新长度为2j的块。因此,预处理时间复杂度为O(nlogn)。这个算法记录了所有长度形如2k的所有询问的结果。从这里可以看出,稀疏表算法的空间复杂度为 O(nlogn)。

    代码:

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int n,a[1001],f[1001][20];
    int rmq(int x,int y)
    {
        int k=floor(log(double(y-x+1)/log(2.0)));
          return min(f[x][k],f[y-(1<<k)+1][k]);
    }
    int main()
    {
        int i,j;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
          scanf("%d",&a[i]),f[i][0]=a[i];
        int k=floor(log(double(n)/log(2.0)));
        for(j=1;j<=k;j++)
          for(i=n;i>=1;i--)
            if(i+(1<<(j-1))<=n)
              f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
        int x,y;
        scanf("%d%d",&x,&y);
        printf("%d",rmq(x,y));
        return 0;
    }

     

     

  • 相关阅读:
    语句覆盖、判断覆盖、条件覆盖、条件判定组合覆盖、多条件覆盖、修正条件覆盖
    Python日志
    Python基础
    curl-awk-grep
    bash使用 变量定义与使用、预定义变量、数组变量、变量计算、掐头去尾与内容替换、数字比较大小、字符串比较、判断文件夹是否存在、逻辑控制if/for/while/
    V模型 W模型 H模型 X模型 前置测试模型
    算法:回文、素数
    JAVA并发思维导图
    工作常见的git命令
    dubbo同步/异步调用的方式
  • 原文地址:https://www.cnblogs.com/jyhywh/p/6065967.html
Copyright © 2011-2022 走看看