SparseTable ST表
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表的更多相关文章
- 模板 - 数据结构 - ST表/SparseTable
SparseTable,俗称ST表,其功能,就是静态的RMQ(区间最值查询)问题的解决.注意传入查询的时候两个参数的合法性,或者可以进行一次全部初始化来使得越界值不产生负面影响.不过访问越界是写程序的 ...
- RMQ问题 - ST表的简单应用
2017-08-26 22:25:57 writer:pprp 题意很简单,给你一串数字,问你给定区间中最大值减去给定区间中的最小值是多少? 用ST表即可实现 一开始无脑套模板,找了最大值,找了最小值 ...
- 算法学习 - ST表 - 稀疏表 - 解决RMQ问题
2017-08-26 21:44:45 writer:pprp RMQ问题就是区间最大最小值查询问题: 这个SparseTable算法构造一个表,F[i][j] 表示 区间[i, i + 2 ^ j ...
- Codeforces 475D 题解(二分查找+ST表)
题面: 传送门:http://codeforces.com/problemset/problem/475/D Given a sequence of integers a1, -, an and q ...
- RMQ算法使用ST表实现
RMQ RMQ (Range Minimum Query),指求区间最小值.普通的求区间最小值的方法是暴力. 对于一个数列: \[ A_1,~ A_2,~ A_3,~ \cdots,~ A_n \] ...
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- 【BZOJ-2006】超级钢琴 ST表 + 堆 (一类经典问题)
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2473 Solved: 1211[Submit][Statu ...
- 【BZOJ-3956】Count ST表 + 单调栈
3956: Count Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 173 Solved: 99[Submit][Status][Discuss] ...
- 【BZOJ-4569】萌萌哒 ST表 + 并查集
4569: [Scoi2016]萌萌哒 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 459 Solved: 209[Submit][Status] ...
- 【BZOJ-4310】跳蚤 后缀数组 + ST表 + 二分
4310: 跳蚤 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 180 Solved: 83[Submit][Status][Discuss] De ...
随机推荐
- P4402 [Cerc2007] robotic sort 机械排序题解
题目链接:[Cerc2007] robotic sort 机械排序 前置知识点:文艺平衡树 具体的我们会将序号下标作为平衡树的键值,这样一来每个节点其实就是数组中的每个位置,又因为这个位置是具有有序性 ...
- 17.3 给内存映射文件指定基地址--《Windows核心编程》
可以使用 MapViewOfFileEx 函数,建议系统把文件映射到指定的地址. 其他参数与 MapViewOfFile 相同,最后一个参数 pvBaseeAddress 指定目标地址.同 Virtu ...
- 《ASP.NET Core 微服务实战》-- 读书笔记(第5章)
第 5 章 创建数据服务 选择一种数据存储 由于我坚持要尽可能的跨平台,所以我决定选用 Postgres,而不用 SQL Server 以照顾 Linux 或 Mac 电脑的读者 构建 Postgre ...
- 开启未来创新之门:.NET Conf China 2023 精彩回顾及资料下载
2023年12月16日-17日,一年一度的 .NET Conf China 2023 中国 .NET 开发者大会在北京盛大举办!大会以第一天主会场 + AI..NET 8.云原生.IoT.前端& ...
- SQLServer复制表及数据的两种方法
1.新表不存在(即复制数据的同时创建与旧表相同结构的新表): select [col1,col2,col3...] into new_table from old_table where 1= ...
- Javascript中的var变量声明作用域问题
先看一下这两段代码的执行结果 var name2 = 'What!'; function a() { if (typeof name2 === 'undefined') { console.log(' ...
- redis大key分析工具redis-rdb-tools
最近1台云Redis的内存曝高,24G的内存占用19G,而且一直增长,想看那些key比较大,腾讯云Redis有大key分析的结果,但是这台没有,估计要找腾讯云的技术刷新一下数据: 分析大key工具,有 ...
- C++常用快读
1.快读相关代码 inline int read() { int x=0,f=0; char ch=getchar(); while(!isdigit(ch))f|=(ch=='-'),ch=getc ...
- Html飞机大战(十五): 上线
好家伙, 我的飞机大战部署上线了 胖虎的飞机大战 感兴趣的可以去玩一下 (怕有人接受不了这个背景,我还贴心的准备切换背景按钮,然而这并没有什么用) 现在,我们停下脚步,重新审视这个游戏 ...
- 2024年,提升Windows开发和使用体验实践 - 小工具篇
前言 本来是一篇文章的,不知不觉写成了系列. 其实开工那几天就已经写好了长文,这几天一忙就没连着发了. 本文介绍一些 Windows 上用的小工具. 美化/折腾/小工具 虽然这是在用 Windows ...