rmq问题:ST表

存板子。O(nlogn)预处理,O(1)查询。空间O(nlogn)。

int d[1000006][25];
int mn[1000006];
void rmq_init()
{
	for(int i=1;i<=n;i++)
		d[i][0]=a[i];
	for(int j=1;(1<<j)<=n;j++)
	  for(int i=1;i+(1<<j)-1<=n;i++)
   		d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]);
   	for(int len=1;len<=n;++len){
		int k=0;
		while((1<<(k+1))<=len)
	  		k++;
		mn[len]=k;
	}
}
int rmq(int L,int R)
{
	int k=mn[R-L+1];
	return min(d[L][k],d[R-(1<<k)+1][k]);
}
时间: 2024-08-13 16:14:50

rmq问题:ST表的相关文章

RMQ问题 - ST表的简单应用

2017-08-26 22:25:57 writer:pprp 题意很简单,给你一串数字,问你给定区间中最大值减去给定区间中的最小值是多少? 用ST表即可实现 一开始无脑套模板,找了最大值,找了最小值,分别用两个函数实现,实际上十分冗余 所以TLE了 之后改成一个函数中同时处理最大值和最小值,就可以了 AC代码如下: /* @theme:poj 3264 @writer:pprp @declare:ST表(sparse table)稀疏表,用动态规划的思想来解决RMQ问题: @date:2017

Codeforces 803G Periodic RMQ Problem ST表+动态开节点线段树

思路: (我也不知道这是不是正解) ST表预处理出来原数列的两点之间的min 再搞一个动态开节点线段树 节点记录ans 和标记 lazy=-1 当前节点的ans可用  lazy=0 没被覆盖过 else 区间覆盖 push_up的时候要注意好多细节,, 数组尽量往大开 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const in

【倍增】RMQ的ST表算法

RMQ问题:给定一个长度为N的区间,M个询问,每次询问Li到Ri这段区间元素的最大值/最小值. RMQ的高级写法一般有两种,即为线段树和ST表. 本文主要讲解一下ST表的写法.(以区间最大值为例) ST表:一种利用dp求解区间最值的倍增算法. 定义:f[i][j]表示i到i+2^j-1这段区间的最大值. 预处理:f[i][0]=a[i].即i到i区间的最大值就是a[i]. 状态转移:将f[i][j]平均分成两段,一段为f[i][j-1],另一段为f[i+2^(j-1)][j-1]. 两段的长度均

RMQ与st表

模板题 P3865 [模板]ST表 代码 实质也是DP,利用倍增获取从i开始长度为\(2^0,2^1,2^2-2^j\)的区间内的最大值. 这样对于任意区间\([l,r]\)都有,令\(dis=r-1+1\)则有\(k_0=2^c,2^{k_0}≤dis≤2^{k_0+1}\)这样在区间\([l,l+k0-1],[r-k0+1,r]\)完全覆盖了这个区域(中间可能有重叠) #include <iostream> #include <cmath> #include <cstdi

(ST表+二分+前缀和)CSU 1879 - Hack Protection

题意: 给定一个序列,求异或和与按位与和相同的区间有几个. 异或和:n个数异或起来.按位与和类似. 分析: 这才是神题,基础算法大杂烩. 问大佬这题的时候,人家只说很不难啊.. 只能说自己太菜. 由于询问区间个数,自然要快速知道某一个区间的异或和与按位与和. 异或和很简单,利用他的性质,直接求前缀和即可. 但是按位与没有和加法和异或类似的性质,无法直接求出. 但是利用之前的知识可以将所有结果预处理出来,而且只要nlogn的复杂度. 就是之前搞RMQ的ST表,很适合离线查询. 几乎不用动的把 mi

RMQ ST表

//ST表 //计算RMQ 即区间最值 //思想:区间dp+倍增 //注:将代码内所有max改成min即可求最小值 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; int n,m,l,r,a[100001]; int Pow[3

二维st表,一种暴力但却快速的二维RMQ利器

先上例题:[HAOI2007]理想的正方形 大部分人都用单调队列,但我不会.首先我们可以暴力枚举所有的可能的正方形,每次我们需要查询RMQ,如果用朴素的方法总复杂度就会变成N^4,你不T谁T 那怎么办,总不可能写正解吧,我们可以用二维st表,预处理N^2logN,每次O(1)查询,N^2水过. 注意,强制类型转换要用大括号括起要转换的东西,例如 (int)(log(n)/log(2)); Code: #include<iostream> #include<cstdio> #incl

HDU 2586 How far away ? &lt;&lt; LCA转RMQ+ST表 求树上任两点最短距离裸题

此题还有LCA+tarjin离线查询做法,详见这里 关于ST表 解决RMQ问题,dp[i][j]表示从第i位开始长度为(1<<j)的区间的最值 维护的时候采用倍增思想,维护dp[i][j+1]=opt(dp[i][j],dp[i+(1<<j)][j]) 查询的时候,两端点为l,r,则长度len=r-l,寻找一个k,使(1<<k)大于等于len/2,这样就使得 [l,l+(1<<k)]和[r-(1<<k),r]覆盖整个区间 然后此时,就可以直接用s

K-th occurrence(后缀树组+划分树+ST表+RMQ+二分)

2019CCPC网络选拔赛1003 HDU6704 题目大意: T个测试样例.一个长度为N的字符串S,之后Q个[l,r,k],表示一个子串S[l,r],求出第k个该子串的下标.起始坐标为1.不存在输出-1. 数据范围:1≤T≤20,  1≤N≤105,  1≤Q≤105,  1≤l≤r≤N,  1≤k≤N,  |S|=N; 赛后补题.参考题解说后缀树组+划分树+ST表+二分. 比赛的时候只会后缀树组不会划分树,赛后仔细想,觉得后缀数组可以,然而并不,会TLE. 补提的时候先是采用后缀树组+划分树

倍增思想到ST表RMQ

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 36864   Accepted: 17263 Case Time Limit: 2000MS Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer Joh