ST表的原理及其实现
ST表类似树状数组,线段树这两种算法,是一种用于解决RMQ(Range Minimum/Maximum Query,即区间最值查询)问题的离线算法
与线段树相比,预处理复杂度同为O(nlogn),查询时间上,ST表为O(1),线段树为O(nlogn)
st表的主体是一个二维数组st[i][j],表示需要查询的数组的从下标i到下标i+2^j - 1的最值,这里以最小值为例
预处理函数:
- int a[];//原始输入数组
- int st[][];//st表
- void init(int n)
- {
- for (int i = ; i < n; i++)
- st[i][] = a[i];
- for (int j = ; ( << j) <= n; j++)
- {
- for (int i = ; i + ( << j) - < n; i++)
- st[i][j] = min(st[i][j - ],st[i + ( << (j - ))][j - ]);
- }
- }
这里首先把从0~n-1的2^0部分进行覆盖,再往下继承
继承这里也很好理解,我们以一个长度为5的数组[5,1,2,3,4]为例
2^0部分覆盖过去自然是5,4,3,2,1
2^1部分的长度为4,从0一直到3,因为从下标为4开始后面只有他自己
st[0][1]是下标为0~1的最小值,自然也就是st[0][0]和st[1][0]的最值
以此往下类推我们可以得出结论:
st[i][j] = min(st[i][j - 1],st[i + 2^(j - 1))][j - 1])
到这里初始化就完成了,注意下标不要越界,如果你对为什么这么处理有困惑的话,请继续看查询
查询函数这里不太好理解
初始化时,每一个状态对应的区间长度都为2^j,由于给出的查询区间长度不一定恰好为2^j,
所以我们要引出一个定理:2^log(a)>a/2 。
https://blog.csdn.net/Hanks_o/article/details/77547380 这里有一段非常非常好理解的解释,这里超级感谢原作者,我本人不能做出更好的解释,他的讲解是这样的:
这个很简单,因为log(a)表示小于等于a的2的最大几次方。
比如说log(4)=2,log(5)=2,log(6)=2,log(7)=2,log(8)=3,log(9)=3…….
那么我们要查询x到y的最小值。
设len=y-x+1,t=log(len)
根据上面的定理:2^t>len/2
从位置上来说,x+2^t越过了x到y的中间!
因为位置过了一半
所以x到y的最小值可以表示为min(从x往后2^t的最小值,从y往前2^t的最小值)
前面的状态表示为mn[t][x]
设后面(从y往前2^t的最小值)的初始位置是k,
那么k+2^t-1=y,所以k=y-2^t+1
所以后面的状态表示为mn[t][y-2^t+1]
所以x到y的最小值表示为min(mn[t][x],mn[t][y-2^t+1]),所以查询时间复杂度是O(1)
查询函数:
- int search(int l, int r)
- {
- int k = (int)(log((double)(r - l + )) / log(2.0));
- return min(st[l][k],st[r - ( << k) + ][k]);
- }
示例程序:
- #include <iostream>
- #include <algorithm>
- using namespace std;
- int a[];//原始输入数组
- int st[][];//st表
- void init(int n)
- {
- for (int i = ; i < n; i++)
- st[i][] = a[i];
- for (int i = ; ( << i) <= n; i++)
- {
- for (int j = ; j + ( << i) - < n; j++)
- st[j][i] = min(st[j][i - ],st[j + ( << (i - ))][i - ]);
- }
- }
- int search(int l, int r)
- {
- int k = (int)(log((double)(r - l + )) / log(2.0));
- return min(st[l][k],st[r - ( << k) + ][k]);
- }
- int main()
- {
- int n,m;
- while (cin >> n >> m)
- {
- for (int i = ; i < n; i++)
- cin >> a[i];
- init(n);
- while (m--)
- {
- int l, r;
- cin >> l >> r;
- cout << search(l,r) << endl;;
- }
- }
- return ;
- }
这里有一个HDU3183的例题大家可以移步看一下具体的使用
https://www.cnblogs.com/qq965921539/p/9609015.html
ST表的原理及其实现的更多相关文章
- ST表
ST表的原理及其实现 ST表类似树状数组,线段树这两种算法,是一种用于解决RMQ(Range Minimum/Maximum Query,即区间最值查询)问题的离线算法 与线段树相比,预处理复杂度同为 ...
- ST表与树状数组
ST表 st表可以解决区间最值的问题.可以做到O(nlogn)预处理 ,O(1)查询,但是不支持修改. st表的大概思路就是用st[i][j]来表示从i开始的2的j次方个树中的最值,查询时就从左端点 ...
- hdu6107 倍增法st表
发现lca的倍增解法和st表差不多..原理都是一样的 /* 整篇文章分成两部分,中间没有图片的部分,中间有图片的部分 分别用ST表求f1,f2表示以第i个单词开始,连续1<<j行能写多少单 ...
- ST表学习总结
前段时间做16年多校联合赛的Contest 1的D题(HDU 5726)时候遇到了多次查询指定区间的gcd值的问题,疑惑于用什么样的方式进行处理,最后上网查到了ST表,开始弄得晕头转向,后来才慢慢找到 ...
- 【BZOJ3784】树上的路径 点分治序+ST表
[BZOJ3784]树上的路径 Description 给定一个N个结点的树,结点用正整数1..N编号.每条边有一个正整数权值.用d(a,b)表示从结点a到结点b路边上经过边的权值.其中要求a< ...
- ST表基础模板
ST表是用来求RMQ问题(求区间最大或最小值问题)的实用数据结构,支持\(O(nlog_n)\)建立,\(O(1)\)查询,是比较高效的结构 其原理实质上是DP(我最讨厌的东西) 题面:屠龙宝刀... ...
- 区间最值的优秀数据结构---ST表
ST表,听起来高大上,实际上限制非常多,仅仅可以求最值问题: 为什么?先从原理看起: st表运用了倍增的思想:st[i][j] = min(st[i][j - 1],st[i + 2^(j - 1)) ...
- 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 ...
随机推荐
- spring boot所有配置
转载 http://blog.csdn.net/lpfsuperman/article/details/78287265 # 日志配置# 日志配置文件的位置. 例如对于Logback的`classpa ...
- 2018.12.30 poj3734 Blocks(生成函数)
传送门 生成函数入门题. 按照题意构造函数: 对于限定必须是出现偶数次的颜色:1+x22!+x44!+...=ex+e−x21+\frac {x^2}{2!}+\frac {x^4}{4!}+...= ...
- 高性能Java RPC框架Dubbo与zookeeper的使用
https://blog.csdn.net/qq_38982845/article/details/83795295
- Linux基础笔记
基本命令: man man 查看手册 (1)pwd 显示路径 (2)cd 切换路径 (3)ls -a;-l;-h;-i;-d (隐藏的:长列表显示:human显示:索引号:只显示列表) (4)c ...
- 下载编译安装Apache HTTP Server 2.4.23以及配置HTTP/HTTPS反向代理
http://blog.csdn.net/gangchengzhong/article/details/52910225 [注意,在编译make时出现的错误并不是文章中说的openssl的版本问题,而 ...
- RGB转换成YCbCr
clear all; close all; clc; img=imread('colorbar.jpg');%('ngc6543a.jpg'); %img=mat2gray(img); %[0,1]; ...
- 20145232 韩文浩 《Java程序设计》第9周学习总结
教材学习内容总结 学习目标 了解JDBC架构 掌握JDBC架构 掌握反射与ClassLoader 了解自定义泛型和自定义枚举 会使用标准注解 JDBC标准主要分为两个部分:JDBC应用程序开发者接口和 ...
- POJ3255-Roadblocks(最短路)
Description Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best ...
- web-day10
第10章WEB10-requet&response篇 今日任务 登录系统后完成文件下载 商城系统注册功能. 教学导航 教学目标 掌握response设置响应头 掌握response重定向和转发 ...
- java基础-day28
第05天 MySQL 今日内容介绍 u 数据库的概述 u MySQL和SQLyog的安装和使用 u SQL语句 第1章 数据库的概述 1.1 数据库的概述 1.1.1 概述 l 什么是数据库 ...