动态规划——稀疏表求解RMQ问题】的更多相关文章

RMQ (Range Minimum/Maximum Query)问题,即区间最值查询问题,是求解序列中的某一段的最值的问题.如果只需要询问一次,那遍历枚举(复杂度O(n))就是最方便且高效的方法,但如果询问次数很多(m次),O(nm)的复杂度可能就不够看了.比较容易想到的优化方法是运用预处理的思想,可以在O(n^2)的时间内预处理出所有区间的最大值,随后每一次查询都只需要O(1)的时间.这种方法在n较小但m非常大的情况下很实用,但如果n也很大的话,无论是空间还是时间都接受不了这个复杂度. 这种…
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)得…
在RMQ的其他实现方法中,有一种叫做ST的算法比较常见. [构建] dp[i][j]表示的是从i起连续的2j个数xi,xi+1,xi+2,...xi+2j-1( 区间为[i,i+2j-1] )的最值. 状态转移方程dp[i][j]=max/min(dp[i][j-1], dp[i+2j-1][j-1]) [查询] 对于一个查询区间[x,y],只要找到一个或者多个2的整数倍长度的刚好区间覆盖[x,y] ,取这些区间最值的最值就是答案了. 如何把[x,y]覆盖完整? 一种办法是把区间的长度按照二进制…
RMQ ( 范围最小值查询 ) 问题是一种动态查询问题,它不需要修改元素,但要及时回答出数组 A 在区间 [l, r] 中最小的元素值. RMQ(Range Minimum/Maximum Query):对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值. 对于 RMQ ,我们通常关心两方面的算法效率:预处理时间和查询时间.解决一般 RMQ 问题的三种方法胜者树 (Winner Tree) O(n)-O(logn)稀疏表 (Spars…
[TJOI2017] DNA Description 求模式串与主串的匹配次数,容错不超过三个字符. Solution 枚举每个开始位置,进行暴力匹配,直到失配次数用光或者匹配成功.考虑到容错量很小,所以每个位置开始的匹配过程中大部分与普通匹配是同样操作,而我们需要的其实就是 LCP 长度,所以预处理出后缀数组和高度数组,建 ST 表支持 RMQ 询问,来加速暴力匹配的过程.时间复杂度 \(O(n \log n)\) #include <bits/stdc++.h> using namespa…
传送门:http://poj.org/problem?id=3264 Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 66241   Accepted: 30833 Case Time Limit: 2000MS Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in…
RMQ问题: RMQ(Range Minimum/Maximum Query),区间最值查询.对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值. RMQ问题可以用线段树和ST表解决. 线段树:查询复杂度O(log n) 可以修改数列中的值 ST表: 查询复杂度 O(1) 无法修改数列中的值,是在线算法 其实ST表就是个动态规划 核心思想:倍增 对于dp[i][j] ,其含义为以i为起点,长度为2^j这个区间的最大值 转移方程就是把这…
RMQ即Range Minimum/Maximun Query,中文意思:查询一个区间的最小值/最大值 比如有这样一个数组:A{3 2 4 5 6 8 1 2 9 7},然后问你若干问题: 数组A下标2~7区间最小的值是多少?       最小值是(1) 数组A下标3~6区间最小的值是多少?       最小值是(4) 数组A下标1~10区间最小的值是多少?      最小值是(1) ...... 专业术语:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标…
///找到一个数字序列包含所有n位数(连续)一次且仅一次 ///暴力打表 ///Time:141Ms Memory:2260K #include<iostream> #include<cstring> #include<cstdio> using namespace std; #define MAX 1000010 bool v[MAX]; char num[6][MAX]; int main() { //freopen("in.txt", &quo…
离线RAQ时,预处理为O(n*lgn),查询为O(1)的算法,比较有意思的一种算法 放个模板在这可以随时看 //ST表(离线) //预处理 O(n*lgn) , 查询 O(1) #include <iostream> #include <stdio.h> using namespace std; #define MX 10005 int n; int a[MX]; ]; // st[i][j] 是第 i 个数为左端点长为 2^j 区间的最大值 int lgn[MX]; //lgn[…
RMQ问题: 给定一个序列,每次询问一个区间最小值 / 最大值. 没有修改. //拿区间最大值来举例. memset(ans, -INF, sizeof(ans)); for (int i = 1; i <= n; i++) ans[i][0] = a[i]; for (int j = 1; (1<<j) <= n; j++) //枚举长度为2^j的区间 for (int i = 1; i+(1<<j)-1 <= n; i++) //枚举区间起点 ans[i][j…
1541:[例 1]数列区间最大值 时间限制: 1000 ms         内存限制: 524288 KB提交数: 600     通过数: 207 [题目描述] 输入一串数字,给你 MM 个询问,每次询问就给你两个数字 X,YX,Y,要求你说出 XX 到 YY 这段区间内的最大数. [输入] 第一行两个整数 N,MN,M 表示数字的个数和要询问的次数: 接下来一行为 NN 个数: 接下来 MM 行,每行都有两个整数 X,YX,Y. [输出] 输出共 MM 行,每行输出一个数. [输入样例]…
ST算法是基于倍增的动态规划算法. #include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> using namespace std; int map[1000005][20]; int N,K; void work() { int i,j; for(j=1;1<<j<=N;j++) for(i=1;i+(1<<j)-1<=N;i++)//i…
RMQ算法,是一个快速求区间最值的离线算法,预处理时间复杂度O(n*log(n))查询O(1),所以是一个很快速的算法,当然这个问题用线段树同样能够解决. 问题:给出n个数ai,让你快速查询某个区间的的最值. 算法分析: (1)预处理 这个算法就是基于DP和位运算符,我们用 dp[i][j] 表示从第 i 位开始,到第 i + 2^j -1 位的最大值或者最小值. 那么我求dp[i][j的时候可以把它分成两部分,第一部分从 i 到 i + 2 ^( j-1 ) - 1 ,第二部分从 i + 2…
Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你求出s的所有回文子串中的最 大出现值. Input 输入只有一行,为一个只包含小写字母(a -z)的非空字符串s. Output 输出一个整数,为逝查回文子串的最大出现值. Sample Input [样例输入l] abacaba [样例输入2] www Sample Output [样例输出l] 7 [样例输出2] 4 HINT 一个串是回文的,当且仅当它从左…
SELECT id, bid, name, title, publisher FROM A where publisher in (select publisher from B group by B.publisher)   或者 SELECT id, bid, name, title, publisher FROM A where exists (select publisher from B where B.publisher = A.publisher group by B.publis…
int lca(int x,int y) { if(de[x]<de[y]) swap(x,y); int d=de[x]-de[y]; for(int i=log2(d);i>=0;i--) { if(d&(l<<i)) { x=fa[x][i]; } } for(int i=log2(n);i>=0;i--) { if(fa[x][i]!=fa[y][i]) { x=fa[x][i]; y=fa[y][i]; } } if(x!=y) { return fa[x]…
Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 11304   Accepted: 3985 Case Time Limit: 1000MS Description Farmer John's cows refused to run in his marathon since he chose a path much too long for their leisurely lifesty…
2017-08-26 22:25:57 writer:pprp 题意很简单,给你一串数字,问你给定区间中最大值减去给定区间中的最小值是多少? 用ST表即可实现 一开始无脑套模板,找了最大值,找了最小值,分别用两个函数实现,实际上十分冗余 所以TLE了 之后改成一个函数中同时处理最大值和最小值,就可以了 AC代码如下: /* @theme:poj 3264 @writer:pprp @declare:ST表(sparse table)稀疏表,用动态规划的思想来解决RMQ问题: @date:2017…
4月4日,应学弟要求去了次学校给小同学们讲了一堂课,其实讲的挺内容挺杂的,但是目的是引出LCA算法. 现在整理一下当天讲课的主要内容: 开始并没有直接引出LCA问题,而是讲了RMQ(Range Minimum/Maximum Query)问题. RMQ指的是对于给定的一个数组,每一次询问一个区间[L,R]中数字的最小或最大值,一个很经典的问题. 一开始没有学生知道如何求解此问题.我将问题弱化,每一次询问[1,R]中数字的最值,有学生打出了求一个min/max数组即可,此为正解. 这是一个相当正确…
ST表,稀疏表,用于求解经典的RMQ问题.即区间最值问题. Problem: 给定n个数和q个询问,对于给定的每个询问有l,r,求区间[l,r]的最大值.. Solution: 主要思想是倍增和区间dp. 状态:dp[i][j] 为闭区间[i,i+2^j-1]的最值. 这个状态与转移方程的关系很大,即闭区间的范围涉及到了转移方程的简便性. 转移方程:dp[i][j]=max(dp[i][j-1],dp[i+2^(j-1)][j-1]). 这是显然的,但这里有个细节:第一个项的范围为[i,i+2^…
下面写提供几个学习LCA和RMQ的博客,都很通熟易懂 http://dongxicheng.org/structure/lca-rmq/ 这个应该是讲得最好的,且博主还有很多其他文章,可以读读,感觉认真读了这篇,都不太需要看别的资料了,百度和谷歌搜索的第一位都是他,好东西大家一起学习 http://scturtle.is-programmer.com/posts/30055 这个博客讲LCA的Tarjan算法个人觉得是比较好的,我看这篇文章,看了1个小时就搞懂了LCA的Tarjan,谢谢博主.可…
RMQ(Range Minimum/Maximum Query)问题是求区间最值问题. 对于长度为 n 的数组 A,进行若干次查询,对于区间 [L,R] 返回数组A中下标在 [L,R] 中的最小(大)值. 可以用线段树来解决这个问题,预处理的复杂度是 O(nlogn),查询的复杂度是 O(logn). 更好的解法是ST算法.Sparse_Table算法,即稀疏表算法,这个方法可以在 O(nlogn) 的预处理后达到 O(1) 的查询代价. 这个算法非常容易实现. 定义 F[ i, k ] 表示从…
rmq问题: 先贴一下定义 范围最值查询 维基百科,自由的百科全书 范围最值查询(Range Minimum Query),是针对数据集的一种条件查询.若给定一个数组 A[1, n],范围最值查询指定一个范围条件 i 到 j,要求取出 A[i, j] 中最大/小的元素. 若 A = [3, 5, 2, 5, 4, 3, 1, 6, 3],条件为 [3, 8] 的范围最值查询返回 1,它是子数组 A[3, 8] = [2, 5, 4, 3, 1, 6]中最小的元素. 通常情况下,数组 A 是静态的…
<题目链接> 题目大意: 给定一段序列,进行q次询问,输出每次询问区间的最大值与最小值之差. 解题分析: RMQ模板题,用ST表求解,ST表用了倍增的原理. #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef long long ll; ; int n,q; ll maxsum[M][],mi…
LCA(Lowest Common Ancestor 最近公共祖先)定义如下:在一棵树中两个节点的LCA为这两个节点所有的公共祖先中深度最大的节点. 比如这棵树 结点5和6的LCA是2,12和7的LCA是1,8和14的LCA是4. 这里讲一下将LCA转化成RMQ问题,进而用st表求解. 首先我们跑一遍dfs,并记录经过的每一个结点(包括回溯的时候),存到一个数组中,这样我就将树的问题转化成线性问题. 等下上图的树好像有些大 这就好多了. 然后就是dfs序列和深度序列 dfs序   1  2  5…
因为最近一段时间接触了一些Leetcode上的题目,发现许多题目的解题思路相似,从中其实可以了解某类算法的一些应用场景. 这个随笔系列就是我尝试的分析总结,希望也能给大家一些启发. 动态规划的基本概念 一言以蔽之,动态规划就是将大问题分成小问题,以迭代的方式求解. 可以使用动态规划求解的问题一般有如下的两个特征: 1.有最优子结构(optimal substructure) 即待解决问题的最优解能够通过求解子问题的最优解得到. 2.子问题间有重叠(overlapping subproplems)…
http://blog.csdn.net/insistgogo/article/details/9929103 这篇博客讲解的很详细了,求区间最大值也可以用st表,时间复杂度O(n log(n)),查询复杂度O(1) 主要是用到区间动规 的思想(虽然我不会区间动规= =) 在求解rmq问题时,st表是很有用的 -------------------------**********************------------------------------------- 要注意的是st表只…
ST表 一.算法介绍 如何快速求解RMQ问题呢?暴力复杂度O(n),线段树复杂度O(n)~O(logn),要是数据规模达到10^7或者更高呢?我们需要一种可以做到O(1)查询的算法,这时就可以用到ST表. 我们用 f[i][j] 表示从 j 位置开始往右 2^i 个数内的最大值,用 g[i][j] 表示从j位置开始往左 2^i 个数内的最大值.所以 f[0][j] , g[0][j] 就为 j 位置上的数,可以在预处理中O(n)处理掉. 接下来我们要求出每个位置的每个 2^i 区间的最大值.可以…
题意:给出n个数和Q个询问(l,r),对于每个询问求出(l,r)之间连续出现次数最多的次数. 解题关键:统计次数,转化为RMQ问题,运用st表求解,注意边界. 预处理复杂度:$O(n\log n)$ #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<cmath> #include<iostream> using names…