Hlg 1832 【线段树 && RMQ】.cpp
题意:
在给出的区间内求出最大买进卖出的差价。
思路:
对于弱数据:维护一个从左到右的最大差价和最小值。即当发现当前值比最小值小的时候更新最小值,否则看一下当前值与之前最小值的差价是否比最大差价大,是就更新最大差价。时间复杂度是O(m*n)
对于强数据:利用线段树维护一个最大差价、最大值和最小值,查询的时候求出询问的范围内左右子树的最大差价,然后再利用RMQ求出[l, mid]的最小值和[mid+1, r]的最大值,然后返回max(df[rt<<1], df[rt<<1|1], RMQ(mid+1, r)-RMQ(l, mid));这个的时间复杂度是O(nlgn)+m*O(nlgn)
Tips:
我的做法是维护了最大值和最小值以便求出最大差值,也可以不维护这个,直接利用RMQ求出最大值和最小值,然后求最大差值。
Code:
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std; const int MAXN = ;
int mx[MAXN<<], mn[MAXN<<], df[MAXN<<];
int dpx[MAXN][], dpn[MAXN][];
int val[MAXN]; void makermq(int n)
{
for (int j = ; (<<j) <= n; ++j)
for (int i = ; i+(<<j)- <= n; ++i) {
dpn[i][j] = min(dpn[i][j-], dpn[i+(<<(j-))][j-]);
dpx[i][j] = max(dpx[i][j-], dpx[i+(<<(j-))][j-]);
}
} int rmqx(int s, int v)
{
int k = (int)(log((v-s+)*1.0)/log(2.0));
return max(dpx[s][k], dpx[v-(<<k)+][k]);
} int rmqn(int s, int v)
{
int k = (int)(log((v-s+)*1.0)/log(2.0));
return min(dpn[s][k], dpn[v-(<<k)+][k]);
} void PushUp(int rt)
{
mx[rt] = max(mx[rt<<], mx[rt<<|]);
mn[rt] = min(mn[rt<<], mn[rt<<|]);
df[rt] = max(df[rt<<], df[rt<<|]);
df[rt] = max(df[rt], mx[rt<<|]-mn[rt<<]);
} void Build(int rt, int l, int r)
{
if (l == r) {
scanf("%d", &mx[rt]);
mn[rt] = mx[rt];
dpn[l][] = dpx[l][] = mx[rt];
return;
}
int mid = (l+r)/;
Build(rt<<, l, mid);
Build(rt<<|, mid+, r);
PushUp(rt);
} int query(int l, int r, int L, int R, int rt)
{
if (L >= l && R <= r) {
return df[rt];
}
int mid = (L+R)/;
int ans = ;
if (r <= mid) ans = query(l, r, L, mid, rt<<);
else if (l > mid) ans = query(l, r, mid+, R, rt<<|);
else {
ans = query(l, r, L, mid, rt<<);
ans = max(ans, query(l, r, mid+, R, rt<<|)); ans = max(ans, rmqx(mid+, r)-rmqn(l, mid));
}
return ans;
} int main()
{
//freopen("in.txt", "r", stdin);
int n;
int q, a, b;
while (~scanf("%d", &n)) {
n++;
memset(df, , sizeof(df));
memset(mx, , sizeof(mx));
memset(mn, , sizeof(mn));
Build(, , n);
makermq(n); scanf("%d", &q);
while (q--) {
scanf("%d %d", &a, &b);
a++, b++;
printf("%d\n", query(a, b, , n, ));
}
puts("");
}
return ;
}
链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1832
外传野史:这道题其实是某学长的面试题,当时那个学长太紧张了,没想清楚,只想到了可以用线段树维护最大值和最小值来解,但是面试官貌似也不认识线段树,然后提示说这个是股票,最小值必须在最大值的左面,这样单纯的维护最大值最小值就不好使了。
所以正解的确是用线段树,但是是用线段树维护差值,并用RMQ来帮忙维护 差值 = 右子树指定范围内最大值-左子树指定范围内最小值 的问题。
这个是zz想到的啦,给他一个good~
Hlg 1832 【线段树 && RMQ】.cpp的更多相关文章
- HDU 1754 I Hate It 线段树RMQ
I Hate It Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=175 ...
- 《白书》上线段树RMQ的实现
白书上的线段树RMQ实现,自己重写了一遍: #include <bits/stdc++.h> using namespace std; const int MAXN=1<<17 ...
- 单点更新线段树 RMQ
D. Xenia and Bit Operations time limit per test 2 seconds memory limit per test 256 megabytes input ...
- CSU 1809 - Parenthesis - [前缀和+维护区间最小值][线段树/RMQ]
题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1809 Bobo has a balanced parenthesis sequenc ...
- UVA 11235 Frequent values 线段树/RMQ
vjudge 上题目链接:UVA 11235 *******************************************************大白书上解释**************** ...
- PKU 2823 Sliding Window(线段树||RMQ||单调队列)
题目大意:原题链接(定长区间求最值) 给定长为n的数组,求出每k个数之间的最小/大值. 解法一:线段树 segtree节点存储区间的最小/大值 Query_min(int p,int l,int r, ...
- Zeratul的完美区间(线段树||RMQ模板题)
原题大意:原题链接 给定元素无重复数组,查询给定区间内元素是否连续 解体思路:由于无重复元素,所以如果区间内元素连续,则该区间内的最大值和最小值之差应该等于区间长度(r-l) 解法一:线段树(模板题) ...
- ACM学习历程—HDU 5289 Assignment(线段树 || RMQ || 单调队列)
Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered fro ...
- dutacm.club_1094_等差区间_(线段树)(RMQ算法)
1094: 等差区间 Time Limit:5000/3000 MS (Java/Others) Memory Limit:163840/131072 KB (Java/Others)Total ...
随机推荐
- Delphi中运行时改变panel的位置及大小(通过wm_SysCommand来实现)
procedure TForm1.pnl1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Int ...
- js 动态切换视频
如图所示,想要一个这样的效果,就是点击下面视频标题时,上面的视频跟着切换,但是要求页面不重新加载. 参考文章在这里 这里贴上部分代码供大家参考. <li id="about_li6&q ...
- IOS 应用的架构解析
首先新建一个IOS 的应用工程,主要讲解一下的文件组成: main.m XXXXDelegete.h\.m MainWindow.xib info.plist 文件 IOS 应用程序由UIKit 封装 ...
- 【翻译】Sencha Ext JS 5公布
原文:Announcing Sencha Ext JS 5 简单介绍 我代表Sencha和整个Ext JS团队,非常自豪的宣布,在今天,Sencha Ext JS 5公布了.Ext JS 5已经迈出了 ...
- Swift - 在界面上生成81个随机红,灰色圆点(SpriteKit游戏开发)
下面是生成一个“围住神经猫”游戏的初始场景: 1,界面下方会生成9*9共81个圆点,同时圆点内部添加文本标签显示索引 2,默认圆点为灰色,每行随机取两个点变为红色 3,奇数行和偶数行有一定的错位,错位 ...
- 中间件(Middleware)
中间件(Middleware) ASP.NET Core开发,开发并使用中间件(Middleware). 中间件是被组装成一个应用程序管道来处理请求和响应的软件组件. 每个组件选择是否传递给管道中的下 ...
- 有没有安全的工作?(99条评论)——结论是没有一劳永逸的工作,要终身学习,IT业刚出道和老手还是有区别的(同样对于新技术,薪资可能是个问题)
作者: 阮一峰 日期: 2015年12月15日 如果你经常使用互联网,可能知道有一种东西叫做Flash. 它是一种软件,用来制作网页游戏.动画,以及视频播放器.只要观看网络视频,基本都会用到它. 七八 ...
- js / ajax 成功提交后怎么跳转到另外一个页面?
把success那段改成 success : function (r) { if ( r.status == 'error' ){ alert(msg[r.msgno]); } else if (r. ...
- “新浪UC”的后江湖时代------易名新浪SHOW重出江湖
说到新浪UC,相信很多老网民应该并不陌生,当年QQ放号收费让新浪UC火爆了好一阵子,而随着QQ的崛起,UC也就渐渐退出了即时通信市场,不过,这并不意味着新浪UC退出了历史舞台,因为目前炙手可热 ...
- 在JAVA中开发应用之html5离线应用
1.环境搭建(Tomcat为例): 在Tomcat中的conf配置文件中web.xml中添加离线配置: <!--HTML5--> <mime-mapping> <ext ...