这里汇集了所有我知道的静态区间最大值做法。

\(O(n)\) 预处理,\(O(n)\) 回答。

每一次询问暴力处理即可。

\(O(n^2)\) 预处理,\(O(1)\) 回答。

预处理出所有的答案。

\(O(n)\) 预处理,\(O(\log n)\) 回答。

维护一棵线段树。

\(O(n\log n)\) 预处理,\(O(1)\) 回答。

维护ST表。

\(O(n)\) 预处理,\(O(\sqrt{n})\) 回答。

对序列分块,预处理出整块的最大值直接查,散块的暴力查。

\(O(n)\) 预处理,期望 \(O(1)\) 回答。

仍然对于原序列分块,预处理出第 \(l\) 个整块到第 \(r\) 个整块的最大值,同时维护出每一个点在它所在块中的前缀最大值和后缀最大值。

这样,对于跨越了块的询问,整块散都可以 \(O(1)\) 查。

但是对于在一个块内的询问,我们仍然只能暴力查,复杂度是 \(O(\sqrt{n})\) 的。

但是,在数据随机的情况下,出现区间左右端点在同一块内的概率是 \(O(\dfrac{1}{\sqrt{n}})\),所以在数据随机的情况下,期望时间复杂度是 \(O(\sqrt{n}\times\dfrac{1}{\sqrt{n}})=O(1)\) 的。

\(O(n)\) 预处理,\(O(1)\) 回答。

对于上述方法,我们发现最大的问题是块内的。

我们假设块长为 \(B\),则我们可以预处理所有整块的ST表,时间复杂度是 \(O(\dfrac{n}{B}\log n)\) 的。

考虑如何做到块内 \(O(1)\) 回答。

我们考虑将某个块内的所有点从左到右加入一个单调队列的过程,例如对于序列 \([1,5,3,2,4]\),有:

编号 单调栈状态
\(1\) \(1\)
\(2\) \(5\)
\(3\) \(5,3\)
\(4\) \(5,3,2\)
\(5\) \(5,4\)

不难发现,对于所有的右端点为 \(r\) 的询问,最终对于答案做贡献的数必然在 \(r\) 对应的单调栈中。具体的,是单调栈中编号 \(\geqslant l\) 的最小编号对应的数。

发现使用状压数组 \(S_i\) 存储对应每一个右端点时,每个点是否在单调栈内,那么每一次的查询是要找到 s[i]>>l 的最低的为 \(1\) 位,这个可以使用 __builtin_ctz O(1)求值。

这样我们对于散块的部分可以做到 \(O(n)\) 预处理,\(O(1)\) 回答。一般块长取 \(B=32\) 以方便使用位运算优化。

例题

Code:

int a[MAXN],Bnum;
int Lm[MAXN],Rm[MAXN];
int stb[MAXN/32+10][30],Log[MAXN/32+10];
int stk[B+1],top;
struct INK{
long long s[B+1];
int *p;
void init(int *num,int lim)
{
p=num;
top=0;
for(int i=1;i<=lim;i++)
{
s[i]=s[i-1];
while(top&&p[stk[top]]<p[i])
s[i]^=(1ll<<stk[top--]);
s[i]^=(1ll<<(stk[++top]=i));
}
}
int get_min(int l,int r){return p[l+__builtin_ctzll(s[r]>>l)];}
}T[MAXN/B+10];
void init(int n)
{
for(int l=1,r;l<=n;l=r+1)
{
Bnum++;
r=min(n,l+B-1);
T[Bnum].init(a+l-1,r-l+1);
Lm[l]=a[l];
for(int i=l+1;i<=r;i++)
Lm[i]=max(Lm[i-1],a[i]);
Rm[r]=a[r];
for(int i=r-1;i>=l;i--)
Rm[i]=max(Rm[i+1],a[i]);
stb[Bnum][0]=Lm[r];
}
for(int i=2;i<=Bnum;i++)
Log[i]=Log[i>>1]+1;
for(int i=1;i<=Log[Bnum];i++)
for(int j=1;j+(1<<i)-1<=Bnum;j++)
stb[j][i]=max(stb[j][i-1],stb[j+(1<<i-1)][i-1]);
}
int STB(int L,int R)
{
int t=Log[R-L+1];
return max(stb[L][t],stb[R-(1<<t)+1][t]);
}
int ques(int l,int r)
{
if(r<l) return 0;
if((l-1)>>5==(r-1)>>5) return T[((l-1)>>5)+1].get_min(((l-1)&(B-1))+1,((r-1)&(B-1))+1);
if(((l-1)>>5)+1==(r-1)>>5) return max(Rm[l],Lm[r]);
else return max(max(Rm[l],Lm[r]),STB(((l-1)>>5)+2,(r-1)>>5));
}

静态RMQ处理方式合辑的更多相关文章

  1. SSH三大框架合辑的搭建步骤

    v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...

  2. 【OpenCV新手教程之十八】OpenCV仿射变换 &amp; SURF特征点描写叙述合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/33320997 作者:毛星云(浅墨)  ...

  3. 【OpenCV新手教程之十七】OpenCV重映射 &amp; SURF特征点检測合辑

    本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/30974513 作者:毛星云(浅墨)  ...

  4. 【OpenCV入门教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑

    http://blog.csdn.net/poem_qianmo/article/details/26977557 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog ...

  5. 【OpenCV新手教程之十四】OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/26977557 作者:毛星云(浅墨) ...

  6. 【Tips】史上最全H1B问题合辑——保持H1B身份终级篇

    [Tips]史上最全H1B问题合辑——保持H1B身份终级篇 2015-04-10留学小助手留学小助手 留学小助手 微信号 liuxue_xiaozhushou 功能介绍 提供最真实全面的留学干货,帮您 ...

  7. 3D Touch:静态快速启动方式

    原文传送门:Add iOS 9’s Quick Actions shortcut support in 15 minutes right now !   苹果在iOS9 上引入3D触控(压力触控)功能 ...

  8. 【OpenCV新手教程之十二】OpenCV边缘检測:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...

  9. [OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

    http://blog.csdn.net/poem_qianmo/article/details/25560901 本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog ...

  10. Java中的静态代理实现方式

    1.编写一个接口类 如:Subject package com.neusoft.pattern.staticProxy; /** * <p>Title:</p> * <p ...

随机推荐

  1. 12_前K个高频元素

    前K个高频元素 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素.你可以按 任意顺序 返回答案.347.力扣题目链接 示例 1: 输入: nums = [1,1,1, ...

  2. kafka 的基本概念及使用场景

    本文为博主原创,未经允许不得转载: 1. Kafka 的使用场景: 1.日志收集:一个公司可以用Kafka收集各种服务的log,通过kafka以统一接口服务的方式开放给各种 consumer,例如ha ...

  3. Verilog仿真实践

    Verilog必须掌握 逻辑仿真工具(VCS)和逻辑综合工具(DC) AndOR module AndOr( output X,Y, input A,B,C ); // A B进行按位与运算 assi ...

  4. 小技巧:WIndows快速创建文件夹

    快速创建文件夹的技巧 1.首先创建文本文档将扩展名更改为.bt,mkdir.bat 2.写入创建文件夹的代码 md 文件夹1 文件夹2 文件夹3 pause 3.双击执行mkdir.bat

  5. Grafana针对内存监控值的学习与使用

    Grafana针对内存监控值的学习与使用 背景 因为学习内存相关的知识, 可以通过pgcacher/sar -r 等命令监控系统信息. 但是现在发现. 不太直观, 所以想着使用别的方式来进行处理. 然 ...

  6. [转帖]How fast are Unix domain sockets?

    https://blog.myhro.info/2017/01/how-fast-are-unix-domain-sockets Jan 3, 2017 • Tiago Ilieve Warning: ...

  7. [转帖]shell 把以空格分隔的变量 分割后的每个字段赋值给变量

    比如我有一个变量 "123 456 789",要求以空格为分隔符把这个变量分隔,并把分隔后的字段分别赋值给变量,即a=123:b=456:c=789 共有3中方法: 法一:先定义一 ...

  8. [转帖]学会BeanShell,才敢说自己懂Jmeter

      https://baijiahao.baidu.com/s?id=1717349581352944280&wfr=spider&for=pc jmeter的BeanShell Sa ...

  9. [转帖]Linux平台shell脚本输入密码,不显示明文

    需求:shell脚本中输入密码,要求不显示明文,需要将其转换为"*"星号,或者不显示 实现方案:有两种实现方案,一是通过stty命令来实现,二是直接使用read来实现 方案一:使用 ...

  10. [转帖]初探Linux CPU动态调频与实测

    https://zhuanlan.zhihu.com/p/33753019 关于 本文主要涉及Linux CPUFreq子系统是什么,为什么需要,怎么用. 并解决在实际测试中遇到的三个问题: scal ...