POJ3264 MRQ算法
poj 3264
给n个数,求任意区间内的最值差。
思路:nlognnlognnlogn 的 算法在这里可以过,有线段树和RMQ算法两种。这里介绍RMQ算法。
RMQ算法是位运算动态规划算法,定义dp[i][j] 为[i,i+2j−1][i,i+2^j -1][i,i+2j−1] 区间内的最值。那么该区间可以划分为两个相同大小的区间[i,i+2j−1−1][i,i+2^{j-1}-1][i,i+2j−1−1] 和[i+2j−1,i+2j−1][i+2^{j-1},i+2^j-1][i+2j−1,i+2j−1] 。
这两个区间用dp数组表示就是dp[i][j−1]dp[i][j-1]dp[i][j−1],dp[i+2j−1][j−1]dp[i+2^{j-1}][j-1]dp[i+2j−1][j−1] 。
所以状态转移方程:mm[i][j]=max/min(mm[i][j-1],mm[i+(1<<(j-1))][j-1]);
mm[i][0]=a[i];
查询[l,r]区间内的时候就找到一个k,(int)k=log2(r−l+1)(int)k=log_2(r-l+1)(int)k=log2(r−l+1) ,目的在于找到[l,r]的一个覆盖,两个区间覆盖[l,r],可以相交。这两个区间长度不超过r-l+1,并且是2的幂。这样子就可以用dp[l][k],dp[r-(1<<k)+1][k] 表示[l,r]区间内最值。
void rmq_init(int n)
{for(int i=1; i<=n; i++){mm[i][0]=mi[i][0]=a[i];}for(int j=1; (1<<j)<=n; j++){for(int i=1; i+(1<<j)-1<=n; i++){mm[i][j]=max(mm[i][j-1],mm[i+(1<<(j-1))][j-1]);mi[i][j]=min(mi[i][j-1],mi[i+(1<<(j-1))][j-1]);}}
}
void rmq(int l,int r)
{int len=r-l+1;int k=(int)(log(r-l+1.0)/log(2.0));int ans1=max(mm[l][k],mm[r-(1<<k)+1][k]);int ans2=min(mi[l][k],mi[r-(1<<k)+1][k]);
}
上面是模板。
对于这个题目来说模板是刚好的。注意的是不要用cin输入,会超时,哪怕使用ios::sync_with_stdio(false)。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define maxn 50000+10
using namespace std;int mm[maxn][100];
int mi[maxn][100];
int a[maxn];
void rmq_init(int n)
{for(int i=1; i<=n; i++){mm[i][0]=mi[i][0]=a[i];}for(int j=1; (1<<j)<=n; j++){for(int i=1; i+(1<<j)-1<=n; i++){mm[i][j]=max(mm[i][j-1],mm[i+(1<<(j-1))][j-1]);mi[i][j]=min(mi[i][j-1],mi[i+(1<<(j-1))][j-1]);}}
}
int rmq(int l,int r)
{int len=r-l+1;int k=(int)(log(r-l+1.0)/log(2.0));int ans1=max(mm[l][k],mm[r-(1<<k)+1][k]);int ans2=min(mi[l][k],mi[r-(1<<k)+1][k]);return ans1-ans2;
}int main()
{int n,m;while(scanf("%d%d",&n,&m)==2){for(int i=1; i<=n; i++)scanf("%d",&a[i]);rmq_init(n);int lef,righ;for(int i=0; i<m; i++){scanf("%d%d",&lef,&righ);printf("%d\n",rmq(lef,righ));}}return 0;
}
POJ3264 MRQ算法相关推荐
- 做acm 需要学的算法
做acm 需要学的算法 转一个搞ACM需要的掌握的算法. 要注意,ACM的竞赛性强,因此自己应该和自己的实际应用联系起来. 适合自己的才是好的,有的人不适合搞算法,喜欢系统架构,因此不要看到别人什 ...
- RMQ ST算法简介
RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就 ...
- acm常见算法及例题
1 acm常见算法及例题 2 3 初期: 4 一.基本算法: 5 (1)枚举. (poj1753,poj2965) 6 (2)贪心(poj1328,poj2109,poj2586) 7 (3)递归和分 ...
- ICPC程序设计题解书籍系列之九:罗勇军《算法竞赛入门到进阶》
罗书<算法竞赛入门到进阶>题目一览 第1章 算法竞赛概述 HDU1000 HDU1089-HDU1096 A+B for Input-Output Practice (I)-(VIII)( ...
- 问,你的算法复习计划是什么?
(另注:这篇文章发到首页,是希望多和大家交流,首先感谢大家) 小学和爸爸一起玩小霸王学习机,看着爸爸照着说明书上的程序在小霸王学习机上打出了一个超级玛丽奥.自己也尝试着打,却没有打出来. 初中,终于把 ...
- 这是关于如何学好算法
这是关于如何学好算法 第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码, 因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打 出来. ...
- ACM常用算法及练习
ACM常用算法及练习 (想学请先放弃) 第一阶段:练bai经典常用算法,下面的每个算法给我打上十du到二十遍,同时自己精简zhi代码 1.最短路(Floyd.Dijstra,BellmanFord) ...
- ACM 算法 阶段性练习 (比较全面)
参考原文:http://blog.csdn.net/zhouhuanchn/article/details/17883005 对原文做了部分删改.未对核心部分做改动. 建议: 做到50行以内的程序不用 ...
- POJ题单及算法训练练习顺序
逛论坛时下面的回复,扒下来自己看的,具体出处也是不祥,总之慢慢学习咯~ 初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj ...
最新文章
- 数字信号的最佳接收理论
- Google ToolBar 3.0 Beta试用
- thinkphp模版常量替换机制
- 尚学python课程---11、linux环境下安装python注意
- [深度学习] 分布式Tensorflow 2.0 介绍(二)
- Windows导出所有计划任务方法
- 字体缩放 SignedDistanceField
- 最小生成树之prim
- 如何清理 Weblogic Server 缓存
- Go 语言真是现在进大厂的捷径?
- UI设计实用素材|寻找一种新的方法来设计网站,单页网站
- scala练习100道解析
- 乱谈B2C系统-算是今年的总结吧
- 转发电子通信类期刊投稿攻略
- 问卷:城市名 转换成 城市线:一线、新一线、二三四五线
- ARM发展史,初步汇总
- word中的神奇的“Alt + X”
- PHP最好的语言的梗的笑话
- python画流星_幻光流星
- 天才小毒妃 第920章 被金执事威胁
热门文章
- 做新媒体运营,如何提高文案写作能力?掌握这4个技巧就够了
- Android常用命令行——gradlew,adb,adb shell
- 跑腿软件开发怎么选择公司
- 044 麦克劳林公式常用函数记忆
- 电脑文件夹怎么同步到手机?
- MyBatis一:关于MyBatis及的搭建过程
- 解决windows10中开代理之后microsoft应用商店无法连接的问题
- c语言输入年月日输出星期几,基姆拉尔森计算公式 (根据输入的年月日输出星期几)...
- 儒释道兼修经典——菜根谭全文及讲解以及弟子规
- 30岁、高中学历、零基础、能不能自学Python?要多久?学到什么程度可以找到工作?