RMQ算法模板

分别写了下标从0和1开始的两种

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<math.h>
 5 using namespace std;
 6
 7 const int maxn=1e5+5;
 8 const int maxl=20;
 9
10 int ma[maxn][maxl];
11 int st[maxn][maxl];
12 int a[maxn],prelog[maxn];
13
14 void initRMQ(int n){
15     for(int i=2;i<=n;++i){
16         prelog[i]=prelog[i-1];
17         if((i&(-i))==i)prelog[i]++;
18     }
19     for(int i=1;i<=n;++i)ma[i][0]=a[i];
20     for(int j=1;(1<<j)<=n;++j){
21         for(int i=1;i+(1<<j)-1<=n;++i){
22             ma[i][j]=max(ma[i][j-1],ma[i+(1<<j-1)][j-1]);
23         }
24     }
25 }
26
27 int askRMQ(int l,int r){
28     if(l>r)swap(l,r);
29     int k=prelog[r-l+1];
30     return max(ma[l][k],ma[r-(1<<k)+1][k]);
31 }
32
33
34 void initST(int n){
35     for(int i=2;i<=n;++i){
36         prelog[i]=prelog[i-1];
37         if((1<<prelog[i]+1)==i)++prelog[i];
38     }
39     for(int i=0;i<n;++i)st[i][0]=a[i];
40     for(int i=n-1;i>=0;--i){
41         for(int j=1;i+(1<<j)-1<n;++j){
42             st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);
43         }
44     }
45 }
46
47 int askST(int l,int r){
48     if(l>r)swap(l,r);
49     int k=prelog[r-l+1];
50     return max(st[l][k],st[r-(1<<k)+1][k]);
51 }
时间: 2024-08-06 16:03:27

RMQ算法模板的相关文章

LCA最近公共祖先 在线算法和离线算法 模板

原理讲解:http://dongxicheng.org/structure/lca-rmq/ 在线算法模板: /** LCA在线算法O(nlogn) 主函数调用: init(); tot=0,dir[1]=0; dfs(1,1); ST(2*n-1); int lca=LCA(u,v); */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #in

tarjan算法模板

var {left表示点 root 没离开栈 vis表示点 root 有没有被访问过} i,n,m,now,time,color,top:longint; v:array[0..10001] of record start:longint;end; e:array[0..100001] of record y,next:longint;end; dfn,low,stack,encolor:array[0..10001] of longint; vis,left:array[0..10001] o

prim算法模板

var g:array[1..10,1..10] of longint; d:array[1..10] of longint; f:array[1..10] of boolean; procedure prim; var i,j,k,min:longint; begin fillchar(g,sizeof(g),0); fillchar(f,sizeof(f),0); for i:=1 to n do d[i]:=g[1,i]; f[1]:=true; for i:=2 to n do begi

bellman-ford算法模板

有SPFA模板,bellman-ford模板显然是多余的. var e:array[1..maxe]of record a,b,w:longint;end; { 距源点s距离 } dis:array[1..maxn]of longint; { 前驱 } pre:array[1..maxn]of longint; m,n,s:longint; procedure relax(u,v,w:longint); begin if dis[u]+w<dis[v] then begin dis[v]:=di

Floyd判最小环算法模板

算法思想:如果存在最小环,会在编号最大的点u更新最短路径前找到这个环,发现的方法是,更新最短路径前,遍历i,j点对,一定会发现某对i到j的最短路径长度dis[i][j]+mp[j][u]+mp[u][i] != INF,这时i,j是图中挨着u的两个点,因为在之前最短路更新过程中,u没有参与更新,所以dis[i][j]所表示的路径中不会出现u,如果成立,则一定是一个环.用Floyd算法来实现.但是对于负环此算法失效,因为有负环时,dis[i][j]已经不能保证i到j的路径上不会经过同一个点多次了.

hdu 1711 KMP算法模板题

题意:给你两个串,问你第二个串是从第一个串的什么位置開始全然匹配的? kmp裸题,复杂度O(n+m). 当一个字符串以0为起始下标时.next[i]能够描写叙述为"不为自身的最大首尾反复子串长度". 当发生失配的情况下,j的新值next[j]取决于模式串中T[0 ~ j-1]中前缀和后缀相等部分的长度, 而且next[j]恰好等于这个最大长度. 防止超时.注意一些细节.. 另外:尽量少用strlen.变量记录下来使用比較好,用字符数组而不用string //KMP算法模板题 //hdu

谈谈RMQ算法

没用的话:好像好久没更博了,无聊就讲讲算法吧(主要找不到水题). 感觉针对初学者,老师教这个算法时没怎么懂,最近(大概1.2个月前吧)老师又教了lca(最近公共祖先,额,可以百度,我就不讲了,可能以后会再写一篇博客关于这个)讲到lca转RMQ才又回来认真复(xue)习(xi).大概搞懂了,本质是dp. 认识RMQ: 要学习RMQ,首先要知道RMQ求什么吧? RMQ简单来说就是求区间的最大值(最小值). 什么?没懂! 举个栗子: 1  -2  9  10  15  38  -9 这里有 7 个数(

初识RMQ算法

这个RMQ算法是专门针对于求最值的高效算法.其思路比较简单,先是利用DP预处理,之后便是查询,方法如下: 假如我们需要查询的区间为(i,j),那么我们需要找到覆盖这个闭区间(左边界取i,右边界取j)的最小幂(可以重复,比如查询5,6,7,8,9,我们可以查询5678和6789). 因为这个区间的长度为j - i + 1,所以我们可以取k=log2( j - i + 1),则有:RMQ(A, i, j)=max{F[i , k], F[ j - 2 ^ k + 1, k]}. 举例说明,要求区间[

HDU 2544 最短路(我的dijkstra算法模板、SPAFA算法模板)

思路:这道题是基础的最短路径算法,可以拿来试一下自己对3种方法的理解 dijkstra主要是从第一个点开始枚举,每次枚举出当当前最小的路径,然后再以那最小的路径点为起点,求出它到其它未标记点的最短距离 bellman-ford 算法则是假设有向网中有n 个顶点.且不存在负权值回路,从顶点v1 和到顶点v2 如果存在最短路径,则此路径最多有n-1 条边.这是因为如果路径上的边数超过了n-1 条时,必然会重复经过一个顶点,形成回路:而如果这个回路的权值总和为非负时,完全可以去掉这个回路,使得v1到v