算法学习 - 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 ...
随机推荐
- linux系统分析命令总结
一张图片
- 剑指Offer——最小的K个数
题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 分析: 建一个K大小的大根堆,存储最小的k个数字. 先将K个数进堆 ...
- Keywords Search---hdu2222(AC自动机 模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章,让你找出有多少个单词在文章里出现过 ...
- 【我的Android进阶之旅】 RxJava 理解Backpressure并解决异常 rx.exceptions.MissingBackpressureException
今天测试人员在测试应用APP的时候应用crash了,查看了下crash log如下所示: java.lang.IllegalStateException: Exception thrown on Sc ...
- PAT 1151 LCA in a Binary Tree[难][二叉树]
1151 LCA in a Binary Tree (30 分) The lowest common ancestor (LCA) of two nodes U and V in a tree is ...
- 模块讲解----time与date time(时间模块)
time和datetime 在python中,通常有一下几种方式来表示时间:1.时间戳:2.格式化时间字符串:3.元祖(struct_time):其中元祖(struct_time分为九个元素) UTC ...
- matlab 保存图片的几种方式
最近在写毕业论文, 需要保存一些高分辨率的图片. 下面介绍几种MATLAB保存图片的 方式. 一. 直接使用MATLAB的保存按键来保存成各种格式的图片 你可以选择保存成各种格式的图片, 实际上对于 ...
- HDevelop数据类型
*图形类型*图像Hwnd:=3600read_image(Image, 'fabrik')disp_obj(Image, Hwnd)*region 区域gen_rectangle1(Rectangle ...
- django 【认证】
一.验证 1.views.py from django.contrib.auth.decorators import login_required from django.contrib.auth i ...
- centos7 vim显示行号
CentOS7下可能有n个账户,让vim显示行号有两种方法:仅让当前用户显示行号和让所有用户显示行号 一.仅让当前用户显示行号 输入命令:vim ~/.vimrc 写入:set nu 保存:wq ...