Sparse Table

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

实现

建表

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

填表

这里用的是动态规划的方法,复杂度为\(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<=floor(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]).

模板类,通过:https://www.luogu.com.cn/problem/P3865:

#include <cmath>
#include <vector>
using namespace std; /*
ST表做静态区间查询,op满足
x op x = x
(x op y) op z = x op (y op z)
query[l,r]从0开始
*/
template <typename T>
class SparseTable {
using VT = vector<T>;
using VVT = vector<VT>;
using func_type = function<T(const T &, const T &)>; VVT ST; static T default_func(const T &t1, const T &t2) { return max(t1, t2); } func_type op; public:
SparseTable(const vector<T> &v, func_type _func = default_func) {
op = _func;
int len = v.size(), l1 = ceil(log2(len)) + 1; ST.assign(len, VT(l1, 0));
for (int i = 0; i < len; ++i) {
ST[i][0] = v[i];
} for (int j = 1; j < l1; ++j) {
int pj = (1 << (j - 1));
for (int i = 0; i + pj < len; ++i) {
ST[i][j] = op(ST[i][j - 1], ST[i + pj][j - 1]);
}
}
} T query(int l, int r) {
int lt = r - l + 1;
int q = max(0, (int)ceil(log2(lt)) - 1);
return op(ST[l][q], ST[r - (1 << q) + 1][q]);
}
};

SparseTable ST表的更多相关文章

  1. 模板 - 数据结构 - ST表/SparseTable

    SparseTable,俗称ST表,其功能,就是静态的RMQ(区间最值查询)问题的解决.注意传入查询的时候两个参数的合法性,或者可以进行一次全部初始化来使得越界值不产生负面影响.不过访问越界是写程序的 ...

  2. RMQ问题 - ST表的简单应用

    2017-08-26 22:25:57 writer:pprp 题意很简单,给你一串数字,问你给定区间中最大值减去给定区间中的最小值是多少? 用ST表即可实现 一开始无脑套模板,找了最大值,找了最小值 ...

  3. 算法学习 - ST表 - 稀疏表 - 解决RMQ问题

    2017-08-26 21:44:45 writer:pprp RMQ问题就是区间最大最小值查询问题: 这个SparseTable算法构造一个表,F[i][j] 表示 区间[i, i + 2 ^ j ...

  4. Codeforces 475D 题解(二分查找+ST表)

    题面: 传送门:http://codeforces.com/problemset/problem/475/D Given a sequence of integers a1, -, an and q ...

  5. RMQ算法使用ST表实现

    RMQ RMQ (Range Minimum Query),指求区间最小值.普通的求区间最小值的方法是暴力. 对于一个数列: \[ A_1,~ A_2,~ A_3,~ \cdots,~ A_n \] ...

  6. POJ3693 Maximum repetition substring [后缀数组 ST表]

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9458   Acc ...

  7. 【BZOJ-2006】超级钢琴 ST表 + 堆 (一类经典问题)

    2006: [NOI2010]超级钢琴 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2473  Solved: 1211[Submit][Statu ...

  8. 【BZOJ-3956】Count ST表 + 单调栈

    3956: Count Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 173  Solved: 99[Submit][Status][Discuss] ...

  9. 【BZOJ-4569】萌萌哒 ST表 + 并查集

    4569: [Scoi2016]萌萌哒 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 459  Solved: 209[Submit][Status] ...

  10. 【BZOJ-4310】跳蚤 后缀数组 + ST表 + 二分

    4310: 跳蚤 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 180  Solved: 83[Submit][Status][Discuss] De ...

随机推荐

  1. STM32 HAL库 USART DMA驱动

    前言 本文是在使用 STM32L4 的串口 DMA 功能时,使用 HAL 库出现的一些问题,通过以下方式解决了 HAL 库中存在 DMA 发送和接收的一些问题. STM32L4 的 DMA 简介 DM ...

  2. PostgreSQL-常用命令汇总

    1.连接到 PostgreSQL 数据库: psql -h 主机名/服务器IP -p 端口号 -U 用户名 -d 数据库名 注意:(1)在服务器上本地登录时,可以使用主机名或者本机IP地址进行登录,但 ...

  3. Linux shell的while循环

    while循环 #!/bin/bash #其中":"表示while循环的条件永远为真的意思 while : do read -p "Enter a number [1-5 ...

  4. python-命令行参数处理 getopt模块详解

    背景 在写脚本程序的时候需要添加一些额外的参数来实现脚本的附加功能或者增强功能,通常的做法是通过sys.argv[i]直接来获取参数的值,但是这个比较局限,要求参数的输入一定要按照顺序. fileNa ...

  5. 【开工大吉】推荐4款开源、美观的WPF UI组件库

    前言 经常有小伙伴在技术群里提问:WPF有什么好用的UI组件库?,今天大姚给大家推荐4款开源.美观的WPF UI组件库. WPF介绍 WPF 是一个强大的桌面应用程序框架,用于构建具有丰富用户界面的 ...

  6. NC52867 Highway

    题目链接 题目 题目描述 In ICPCCamp there were n towns conveniently numbered with \(1, 2, \dots, n\) connected ...

  7. Git识别文件权限修改

    刚打开IDE,工作区的代码状态全部变成修改未提交的状态了?这是这么回事?这是因为Git忽略文件权限或者拥有者改变导致的git状态变化.默认Git会记录文件的权限信息,如果文件的权限信息被修改,在Git ...

  8. SATA学习笔记——Link Layer 加扰/解扰/CRC

    一.故事前传 我们之前说到Link layer的结构,link layer的作用大致可以包括以下几点: Frame flow control CRC的生成与检测 对数据与控制字符的Scrmable/D ...

  9. 【leetcode】合并 k 个有序链表,我给了面试官这 5 种解法

    开胃菜 在进入本节的正题之前,我们先来看一道开胃菜. 题目 21. 合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1 ...

  10. Ubuntu20.04安装记录

    在Ubuntu下将iso文件刻录到U盘, 可以使用系统自带的Startup Disk Creator. 分区方式 使用整个硬盘, 一个512G SSD, 使用默认的分区方式, 会创建一个512M的EF ...