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]).

  • 相关阅读:
    Solution: Win 10 和 Ubuntu 16.04 LTS双系统, Win 10 不能从grub启动
    在Ubuntu上如何往fcitx里添加输入法
    LaTeX 笔记---Q&A
    Hong Kong Regional Online Preliminary 2016 C. Classrooms
    Codeforces 711E ZS and The Birthday Paradox
    poj 2342 anniversary party
    poj 1088 滑雪
    poj 2479 maximum sum
    poj 2481 cows
    poj 2352 stars
  • 原文地址:https://www.cnblogs.com/rookiezjz/p/12771901.html
Copyright © 2011-2022 走看看