算法学习 - 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 ...
随机推荐
- mysql5.7.22在centos7.5下的安装
1.下载,解压 把下载的文件放到 /app/programs/目录下 tar -zxvf mysql-5.7.22-linux-glibc2.12-x86_64.tar.gz 地址:https://d ...
- 使用 postMessage + iframe 实现跨域通信
一.postMessage window.postMessage() 方法可以安全地实现跨源通信.通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(44 ...
- mysql一个特殊的条件.字符串除以0的结果.
select * form user where username = ''/1; 一开始一看以为还是错误的语法.... 结果出来一堆结果.. 原来条件是 ''除以1 ''除以1 结果是什么 ...
- 网络编程 - socket通信/粘包/文件传输/udp - 总结
socket通信 1.简单的套接字通信 import socket phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.bin ...
- SpringCloud 进阶之Ribbon和Feign(负载均衡)
1. Ribbon 负载均衡 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端,负载均衡的工具; 1.1 Ribbon 配置初步 1.1.1 修改 micros ...
- kafka-stream数据清洗
1.数据清洗业务类LogProcessor package com.css.kafka.kafka_stream; import org.apache.kafka.streams.processor. ...
- 浅谈virtualenv(虚拟环境)
简介 virtualenv为应用提供了隔离的Python运行环境,解决了不同应用间多版本的冲突问题. 例如: 如果我们要同时开发多个应用程序,那这些应用程序都会共用一个Python,就是安装在系统的P ...
- 【我的Android进阶之旅】解决Center OS 64位系统编译Android APP报错error=2和finished with non-zero exit value 127
一.错误描述 1.问题 java.io.IOException: error=2, 没有那个文件或目录 今天在刚重新搭建好的64位的Center OS上安装好了Android SDK,Jenkins, ...
- Java 运算符及优先级
运算符 分割符: , ; [] () 算数运算符: + - * / % ++ -- 关系运算符: > < >= <= == != 逻辑运算符: ! & | ^ & ...
- DOM扩展学习笔记
对DOM的两个主要扩展是Selectors API(选择符API)和HTML5,还有一个不太瞩目的Element Traversal元素遍历规范为DOM添加了一些属性,另外还有一些专有扩展. 选择符A ...