算法学习 - ST表 - 稀疏表 - 解决RMQ问题
2017-08-26 21:44:45
writer:pprp
RMQ问题就是区间最大最小值查询问题;
这个SparseTable算法构造一个表,F[i][j] 表示 区间[i, i + 2 ^ j -1]的最大或者最小值
ST分为两个部分
1、nlogn的预处理
预处理主要用到了动态规划,二分区间每个区间长度为 2 ^ (j -1)找到一个递推关系;
F[i][j] = min(F[i][j - 1],F[i + (1 << (j - 1))][j - 1]);
2、查询部分更为巧O(1)得到询问结果
对于任意一个区间【n,m】来说,可以将其划分为两个以上区间的和
【m,n】 = 【m, m+2^k-1】 + 【n-2^k-1,n】
其中k = log2(n-m+1)
实现的代码如下:
/*
@theme:ST表(sparse table)稀疏表
@writer:pprp
@declare:用动态规划的思想来解决RMQ问题;
@date:2017/8/26
*/ /*方程
F[i,j]:区间[i,i + 2^j - 1]的最小值,此时区间长度为2^j
转移方程:F[i,j] = min(F[i,j - 1],F[i + 2^(j - 1),j - 1])
初始化:F[i,0] = nArr[i];
*/ #include <bits/stdc++.h> using namespace std; int F[][];//待比较元素的个数最大为1百万 void SparseTable(int a[], int len)
{
//初始化
for(int i = ; i < len ; i++)
F[i][] = a[i];
//递推
//找到j的范围log2(n)
int nlog = int(log(double(len))/log(2.0));
for(int j = ; j <= nlog; j++)
{
for(int i = ; i < len ; i++)
{
//区间右端点不能超过数组最后一位下标
if((i + ( << j) -) < len )
{
F[i][j] = min(F[i][j - ],F[i + ( << (j - ))][j - ]);
}
}
}
} int RMQ(int a[], int len, int Start, int End)
{
//中间变量的选取log2(len)
int nlog = (int)(log(double(End-Start+))/log(2.0)); return min(F[Start][nlog], F[End - ( << nlog) + ][nlog]);
} int main()
{
int a[] = {,,,,,,,,,,,,,,,}; for(int i = ; i < ; i++)
{
cout << a[i] <<" ";
}
cout << endl; SparseTable(a,);
int l, r;
while(cin >> l >> r)
{
cout << RMQ(a,,l,r) << endl;
}
return ;
}
ST模板
#include <bits/stdc++.h> using namespace std; int F[][];
void ST(int a[],int len)
{
for(int i = ; i < len ; i++)
F[i][] = a[i];
int nlog = int(log(double(len))/log(2.0));
for(int j = ; j <= nlog; j++)
{
for(int i = ; i < len ; i++)
{
if(i+(<<j)- < len)
F[i][j] = max(F[i][j-],F[i+(<<(j-))][j-]);
}
}
} int RMQ(int a[],int len, int l, int r)
{
int nlog = floor(log(double(r-l+))/log(2.0));
return max((F[l][nlog]),F[r-(<<nlog)+][nlog]);
} int main()
{
int a[];
int n;
cin >> n;
for(int i = ; i < n ; i++)
cin >> a[i];
ST(a,n);
int l,r;
int cas;
cin >> cas;
while(cas--)
{
cin >> l >> r;
cout << RMQ(a,n,l,r) << endl;
} return ;
}
算法学习 - ST表 - 稀疏表 - 解决RMQ问题的更多相关文章
- [poj3264]rmq算法学习(ST表)
解题关键:rmq模板题,可以用st表,亦可用线段树等数据结构 log10和log2都可,这里用到了对数的换底公式 类似于区间dp,用到了倍增的思想 $F[i][j] = \min (F[i][j - ...
- 算法学习——st表
st表是一种基于倍增思想的DP. 用于求一个数列中的某个区间的最大/最小值. 用st[i][j]表示从第i个开始往后2^j个点,最大的是多少. 我们令k[i]表示2^i等于多少 那么有转移方程 st[ ...
- RMQ (Range Minimal Query) 问题 ,稀疏表 ST
RMQ ( 范围最小值查询 ) 问题是一种动态查询问题,它不需要修改元素,但要及时回答出数组 A 在区间 [l, r] 中最小的元素值. RMQ(Range Minimum/Maximum Query ...
- ST表解决RMQ问题
RMQ问题: RMQ(Range Minimum/Maximum Query),区间最值查询.对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间 ...
- 基于稀疏表(Sparse Table)的RMQ(区间最值问题)
在RMQ的其他实现方法中,有一种叫做ST的算法比较常见. [构建] dp[i][j]表示的是从i起连续的2j个数xi,xi+1,xi+2,...xi+2j-1( 区间为[i,i+2j-1] )的最值. ...
- [算法模板]ST表
[算法模板]ST表 ST表和线段树一样,都能解决RMQ问题(范围最值查询-Range Minimum Query). 我们开一个数组数组\(f[maxn][maxn\log_2]\)来储存数据. 定义 ...
- 动态规划——稀疏表求解RMQ问题
RMQ (Range Minimum/Maximum Query)问题,即区间最值查询问题,是求解序列中的某一段的最值的问题.如果只需要询问一次,那遍历枚举(复杂度O(n))就是最方便且高效的方法,但 ...
- 用ST解决RMQ问题
用ST算法解决RMQ(区间最值问题) 在解决CF上的6E Exposition时,用到了RMQ+二分的方法.学习了用ST来快速解决RMQ问题,因此做一个小记 建表 用DP的方式来建ST. dp[i][ ...
- mysql中相关,无关子查询,表与表之间的关系以及编码和乱码的解决
※MySQL中的字符编码(注意,utf8中没有'-',跟Java中不一样)SHOW VARIABLES; //查看系统变量//查询字符编码相关的系统变量SHOW VARIABLES WHERE var ...
随机推荐
- 属性attribute和property的区别
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content ...
- Java 内省(Introspector)深入理解
Java 内省(Introspector)深入理解 一些概念: 内省(Introspector) 是Java 语言对 JavaBean 类属性.事件的一种缺省处理方法. JavaBean是一种特殊的类 ...
- Python并行编程(五):线程同步之信号量
1.基本概念 信号量是由操作系统管理的一种抽象数据类型,用于在多线程中同步对共享资源的使用.本质上说,信号量是一个内部数据,用于标明当前的共享资源可以有多少并发读取. 同样在threading中,信号 ...
- 网络爬虫值scrapy框架基础
简介 Scrapy是一个高级的Python爬虫框架,它不仅包含了爬虫的特性,还可以方便的将爬虫数据保存到csv.json等文件中. 首先我们安装Scrapy. 其可以应用在数据挖掘,信息处理或存储历史 ...
- HTTP来源地址
HTTP来源地址(referer,或HTTP referer),是HTTP表头的一个字段,用来表示从哪儿链接到目前的网页,采用的格式是URL. 换句话说,借着HTTP来源地址,目前的网页可以检查访客从 ...
- 主成分分析PCA学习一条龙
转自:https://yoyoyohamapi.gitbooks.io/mit-ml/content/%E7%89%B9%E5%BE%81%E9%99%8D%E7%BB%B4/articles/PCA ...
- PAT 1038 Recover the Smallest Number[dp][难]
1038 Recover the Smallest Number (30 分) Given a collection of number segments, you are supposed to r ...
- 模块讲解----json模块(跨平台的序列化与反序列化)
一.json的特点 1.只能处理简单的可序列化的对象:(字典,列表,元祖) 2.json支持不同语言之间的数据交互:(python - go,python - java) 二.使用场景 1.玩 ...
- oracle的字符集设置与乱码
oracle的字符集设置与乱码 字符集问题一直叫人头疼,究其原因还是不能完全明白其运作原理. 在整个运行环节中,字符集在3个环节中发挥作用: 1.软件在操作系统上运作时的对用户的显示,此时采用操作系统 ...
- 深度分析ORACLE热点块问题
1.热点块的定义 数据库的热点块,从简单了讲,就是极短的时间内对 少量数据块进行了过于频繁的访问.定义看起来总是很简单的,但实际在数据库中,我们要去观察或者确定热点块的问题,却不是那么简单了.要深刻地 ...