区间最值(RMQ)的几种方法(知识整理+板子总结)
相当于总结一波,以后就从这里扒RMQ的板子
个人觉得博客的这个粘代码背景没我的黑底白字好看QAQ
代码总是越敲越熟的嘛……知识沉积的过程……
到时候改一改,传参的时候把数组名一起传进去,就能当小黑盒用了
法一(单调队列,O(n)):
//区间连续k个的最小 传进去下标 deque<int>q;for(int i=1;i<k;++i){while(!q.empty()&&high[q.back()]>high[i])q.pop_back();q.push_back(i); }for(int i=k;i<n;++i){while(!q.empty()&&high[q.back()]>high[i])q.pop_back();q.push_back(i); ans=max(ans,high[q.front()]);if(q.front()<=i-k+1)q.pop_front();}
法二(multiset,O(nlogn)):
这个东西和set其实没啥区别,
允许数字被重复插入,操作差不太多
//区间连续k个的最小 传进去值 multiset<int>q; for(int i=1;i<k;++i)q.insert(high[i]);for(int i=k;i<n;++i){q.insert(high[i]);ans=max(ans,*q.begin());q.erase(q.find(high[i-k+1]));}
法三(ST表RMQ,预处理O(nlogn),查询O(1)):
void ST(int n)
{for(int i=1;i<n;++i)dp[i][0]=high[i];for(int j=1;(1<<j)<n;++j){for(int i=1;i+(1<<j)-1<n;++i){dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);}}
}int RMQ(int l,int r)
{int k=log(r-l+1)/log(2);return min(dp[l][k],dp[r-(1<<k)+1][k]);
}
ST(n);
for(int i=1;i+k-1<n;++i)
ans=max(ans,RMQ(i,i+k-1));
ST表后续(以poj3264为例):
感觉还是这个好用,mx[i][j]代表下标从i开始的连续区间长度为的最大值,mn[i][j]为最小值
然后询问还是一样的询问方法,用换底公式搞一下区间长度,取左取右即可
现在还是重在彻底理解原理之后手敲啊,别成天抄板子
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=1e6+10;
int n,q;
int mx[maxn][22],mn[maxn][22];
int l,r,v;
void ST(int n)
{for(int len=1;(1<<len)<=n;++len){for(int i=1;i+(1<<len)-1<=n;++i){mx[i][len]=max(mx[i][len-1],mx[i+(1<<(len-1))][len-1]);mn[i][len]=min(mn[i][len-1],mn[i+(1<<(len-1))][len-1]);}}
}
int RMQ(int l,int r,int op)
{int k=log(r-l+1)/log(2);int ans;if(!op)ans=max(mx[l][k],mx[r-(1<<k)+1][k]);else ans=min(mn[l][k],mn[r-(1<<k)+1][k]);return ans;
}
int main()
{while(~scanf("%d%d",&n,&q)){for(int i=1;i<=n;++i){scanf("%d",&v);mx[i][0]=mn[i][0]=v;}ST(n);for(int i=1;i<=q;++i){scanf("%d%d",&l,&r);printf("%d\n",RMQ(l,r,0)-RMQ(l,r,1));}}return 0;
}
法四(线段树,预处理O(nlogn),查询O(logn))
挺好写的吧,基础操作……
有前面那么优秀的几种就不写这个了QAQ
区间最值(RMQ)的几种方法(知识整理+板子总结)相关推荐
- 在java中的交换方法有哪些_java中交换两个变量的值有哪几种方法,交换两个变量a和b的值...
java中交换两个变量的值有哪几种方法在Java中,有哪些方法可以交换两个变量的值, 方法: 1.定义临时变量 2.没有必要定义临时变量 3.使用位运算符 (学习视频分享:java课程) 代码示例: ...
- 通过Value获取Map中的键值Key的四种方法
1 简介 我们都知道Map是存放键值对<Key,Value>的容器,知道了Key值,使用方法Map.get(key)能快速获取Value值.然而,有的时候我们需要反过来获取,知道Value ...
- python两个元组相加_Python两个字典键同值相加的几种方法
Python中,如何合并两个键相同,值为元祖类型的字典? dicxs={"李明":("男",19), "杨柳":("女" ...
- Web 之 html 如何显示隐藏Html元素的两种方法简单整理
Web 之 html 如何显示隐藏Html元素的两种方法简单整理 目录 Web 之 html 如何显示隐藏Html元素的两种方法简单整理 一.简单介绍 二.实现原理 三.注意事项 四.代码示例 一.简 ...
- Python两个字典键同值相加的几种方法
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/Jerry_1126/article/d ...
- C语言函数怎么像python那样返回多个值?(三种方法:1、设置全局变量 2、传递指针 3、使用结构体返回不同类型的数据)
引用文章:c语言函数可不可以返回多个值 文章目录 方法一:设置全局变量 例如:利用一个函数求出正方形的周长和面积. 方法二:使用数组名或指针作为函数的形参 实例2:编写函数求一维整形数组的最大值与最小 ...
- 在form2中调用form1中的方法并改变form1中控件值的另一种方法
在窗体编程中,经常碰到到要在form2中调用form1中的方法并改变form1中控件值,但是又不能用new form1这种方法,因为这是生成一个实例. 网上有些说法是用委托和事件,笔者尝试没有成功,可 ...
- excel多条件计数python_Excel统计满足条件的不重复值个数的8种方法,第三种方法最适合新手!我真的入门了!...
问题很常见,但是对新手来说又比较棘手,所以我们来一期,系统讲讲,个人我个人的知识储备,大概写了8种,涵盖Excel的方方面面!最后一种也满足一下大家对于Python的好奇! 友情提醒:应该是目前你所能 ...
- int 互换 java_Java基础中Int类型变量值互换的几种方法
在很多时候,我们会使用到将两个整型变量值进行互换,比如冒泡排序,通过判断来将数组变量的值逐步交换,那么怎么交换值才能最有效最节省空间呢? 首先,我们会想到的,用一个零时变量来做中间的过度存储空间,这是 ...
最新文章
- 600页!分享珍藏很久的《推荐系统学习手册》(附下载链接及入门经验)
- 【MATLAB】图像导出 ( 导出绘制的图像 | 图像设置 )
- VHDL/Verilog编译错误总结
- 方形物体绕中心旋转的扭力_三维旋转
- 51单片机音乐播放器c语言,51单片机之简单的音乐播放器
- hdu 1872 稳定排序
- 音视频开发(35)---麦克风阵列语音增强
- C/C++ Windows API——Tcp 客户端 服务器
- linux查看log日志在哪,如何查看linux的系统log日志
- 【原创手写笔记】面试准备,关于Adaboost GBDT算法你需要知道的那些
- Excel函数公式大全—VLOOKUP函数
- 创建AWS VPC Peering
- 服务器iscsi如何修复,服务器重启后,iSCSI目标卡住了重新连接
- 台式计算机diy,自己组装DIY台式电脑知识
- 计算机网络的定义和分类
- Need和Want有何不同?
- 大厂代码规范及个人本学期的代码规范
- 软考初级程序员上午单选题(13)
- 【HDU5984】Pocky(数学)
- Python:实现寻峰算法(附完整源码)
热门文章
- 懂了这个道理,你才有可能赚大钱!
- Python入门书籍推荐——《笨办法学Python》
- Flutter Row 或者 Column 的拉伸效果,CrossAxisAlignment.stretch
- html5实现浏览器自动全屏,[JavaScript] 用html5 js实现浏览器全屏
- javassist.NotFoundException:XXXXXXXXXXXXXXXXXXXX
- 【Python自学】七个超强学习网站,你值得拥有!
- 正则语言(转的 大额_skylar )
- dbvisualizer 使用Database URL链接Sybase数据库方式
- 阿里巴巴矢量库的用法
- tomcat中ajp及8009端口用处