zoukankan      html  css  js  c++  java
  • SparseTable ST表

    Sparse Table

    ST表是一个静态二维数组st[i][j],作用是快速查询(O(1))区间最值(不只是最值,可重复贡献问题都可以用),st[i][j]代表的是在以引索i为起点,长度为(2^j)的区间内最值,缺点是只能静态查询,不支持修改。

    实现

    建表

    对于要查询的数组a[n],首先创建一个二维数组st[i][j],(0le i<n, ; 0le jle log_{(n)}). 解释一下j的值域,j代表查询区间的大小((2^j)),所以,如果我们要查询区间a[0,n)的最值,那么就是st[0][j],其中(j=lceil log_2n ceil).

    填表

    这里用的是动态规划的方法,复杂度为(nlog n)。一个长度为(2^j)区间的最值就等于这个区间前(2^{j-1})个元素的最值和后(2^{j-1})个元素的最值中的最值。所以状态转移方程为(st[i][j] = max(st[i][j-1], st[i+2^{j-1}, j-1])).

    for(int i=0; i<n; ++i) 
        st[i][0] = a[i]; //长度为2^0=1的区间就是a[i]本身
    
    for(int j=1; j<=ceil(log(n)/log(2)); ++j)
        for(int i=0; i<n; ++i) {
            if(i+(1<<j) > n+1) break;  //区间越界
            st[i][j] = max(st[i][j-1], st[i+(1<<(j-1))][j-1]);
        }
    

    查询

    因为ST表只能的查询区间长度都为2的幂次((2^j)),那么我们要查询的区间长度不是2的幂次怎么办.

    任意一个正整数都可以拆分成若干个2的幂次的和。例如我们查询区间[3,10)区间长度为7,7可以拆分为1+2+4,那么我们要查询的最值就是max(st[3][0], st[4][1], st[6][2]).

  • 相关阅读:
    静态库中的静态变量连接失败的解决
    (转)Virtual PC 2007虚拟网络设置
    (zt)iPhone Developer注册
    (zt)正则表达式30分钟入门教程
    (zt)Flex SDK 3.2和Flex Builder 3.0.2升级
    (转)完成端口之性能优化
    (摘)法拉利年代型号
    安装windows下的NDS开发环境
    [C#]小问题
    javascript "未结束字符串"
  • 原文地址:https://www.cnblogs.com/rookiezjz/p/12771901.html
Copyright © 2011-2022 走看看