zoukankan      html  css  js  c++  java
  • Sparse Table

    Sparse Table

    Sparse Table是一种简单的离线数据结构,主要用于解决RMQ(Range Maximum/Minimum Query, 区间最值查询)问题。它主要应用倍增的思想,可以实现 (O(nlogn)) 预处理、 (O(1)) 查询。

    ST使用一个二维数组 (f) ,先预处理范围内所有的 (f[a][b] = max ({A_{i}})_{iin[a, a+2^b-1]})。查询时再利用这些子区间算出待求区间的最大值。

    具体的查询方法:对于区间 $[l, r] $,我们取其两个等长的连续子区间将其覆盖。注意,这两个子区间不一定交集为空。由于区间的长度为 (r-l+1) ,而我们预处理的(f)数组将区间划分为 (2) 的整数倍,因此可以将区间 ([l,r]) 拆分为两个长度为 (2^{lfloor{log_2{(r-l+1)} floor}})的子区间 ,分别为 ([l, l+2^s-1])([r-2^s+1,r])

    preview

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5+5;
    
    int n, m, l, r;
    int f[N][21]; // 第二维根据数据范围决定, 不小于log(N)
    int Log2[N];
    
    int main(){
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; ++i){
            scanf("%d", &f[i][0]);
        }
        for(int i = 1; i <= n; ++i){ // dim 2
            for(int j = 1; j + (1 << i)-1 <= n; ++j){ // dim 1
                f[j][i] = max(f[j][i-1], f[j+(1<<(i-1))][i-1]);
            }
        }
        for(int i = 2; i <= n; ++i){
            Log2[i] = Log2[i/2] + 1;
        }
        
        while(m--){
            scanf("%d%d", &l, &r);
            int s = Log2[r-l+1];
            printf("%d
    ", max(f[l][s], f[r-(1<<s)+1][s]));
        }
        
        system("pause");
        return 0;
    }
    

    其实ST表不仅能处理最大值/最小值,凡是符合结合律且可重复贡献的信息查询都可以使用ST表高效进行。什么叫可重复贡献呢?设有一个二元运算 (f(x,y)) ,满足 (f(a,a)=a) ,则 (f) 是可重复贡献的。显然最大值、最小值、最大公因数、最小公倍数、按位或、按位与都符合这个条件。可重复贡献的意义在于,可以对两个交集不为空的区间进行信息合并。

    ---- suffer now and live the rest of your life as a champion ----
  • 相关阅读:
    Spring三大器
    SpringBoot启动过程
    linux常用命令
    Controller当中的参数与返回值
    Spring加载context的几种方法
    Spring基础(imooc)
    SpringMVC框架学习
    Spring MVC(imooc)
    springAOP基础
    《别傻了,你的中年危机真不是因为穷》
  • 原文地址:https://www.cnblogs.com/popodynasty/p/14709311.html
Copyright © 2011-2022 走看看