【BZOJ4149】[AMPPZ2014]Global Warming 单调栈+RMQ+二分
【BZOJ4149】[AMPPZ2014]Global Warming
Description
Input
Output
Sample Input
8 3 2 5 2 3 4 6 3 6
Sample Output
HINT
选出的子序列为5,2,3,4,6,3,只有唯一的最小值2和唯一的最大值6。
题解:首先我们用单调栈枚举每个数作为最大值的影响区间,然后枚举这个最大值。此时最小值怎么取呢?由于我们已经确定了最大值以及最大值的影响区间,那么最小值一定是取这个区间中的最小值,因为其他数的影响区间一定不会比最小值的影响区间大。区间最小值可以用RMQ处理。但是区间中可能有多个最小值,而影响区间包含当前最大值的只有一个,所以我们用vector维护每个数的所有出现位置,然后二分找到当前位置的前驱即后继,合法的最小值要么是前驱要么是后继。然后求一下最大值和最小值影响区间的交集即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=500010;
int n,m,top,ans,pos;
int v[maxn],mn[20][maxn],Log[maxn],lm[maxn],rm[maxn],ln[maxn],rn[maxn],st[maxn];
vector<int> p[maxn];
struct number
{
int val,org;
}num[maxn];
bool cmp(const number &a,const number &b)
{
return a.val<b.val;
}
inline int getmn(int a,int b)
{
int k=Log[b-a+1];
return min(mn[k][a],mn[k][b-(1<<k)+1]);
}
inline void updata(int a,int b)
{
if(a>ans||(a==ans&&b<pos)) ans=a,pos=b;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
int main()
{
n=rd();
int i,j,a,b;
for(i=1;i<=n;i++) num[i].val=rd(),num[i].org=i;
sort(num+1,num+n+1,cmp);
for(i=1;i<=n;i++)
{
if(i==1||num[i].val>num[i-1].val) m++;
v[num[i].org]=m;
}
for(i=2;i<=n;i++) Log[i]=Log[i>>1]+1;
for(i=1;i<=n;i++) p[v[i]].push_back(i),mn[0][i]=v[i];
for(j=1;(1<<j)<=n;j++) for(i=1;i+(1<<j)-1<=n;i++) mn[j][i]=min(mn[j-1][i],mn[j-1][i+(1<<(j-1))]);
for(st[top=0]=0,i=1;i<=n;i++)
{
while(top&&v[st[top]]<v[i]) top--;
lm[i]=st[top]+1,st[++top]=i;
}
for(st[top=0]=0,i=1;i<=n;i++)
{
while(top&&v[st[top]]>v[i]) top--;
ln[i]=st[top]+1,st[++top]=i;
}
for(st[top=0]=n+1,i=n;i>=1;i--)
{
while(top&&v[st[top]]<v[i]) top--;
rm[i]=st[top]-1,st[++top]=i;
}
for(st[top=0]=n+1,i=n;i>=1;i--)
{
while(top&&v[st[top]]>v[i]) top--;
rn[i]=st[top]-1,st[++top]=i;
}
for(i=1;i<=n;i++)
{
j=getmn(lm[i],rm[i]);
b=lower_bound(p[j].begin(),p[j].end(),i)-p[j].begin(),a=b-1;
if(a>=0&&rn[p[j][a]]>=i) updata(min(rm[i],rn[p[j][a]])-max(lm[i],ln[p[j][a]])+1,max(lm[i],ln[p[j][a]]));
if(b<(int)p[j].size()&&ln[p[j][b]]<=i) updata(min(rm[i],rn[p[j][b]])-max(lm[i],ln[p[j][b]])+1,max(lm[i],ln[p[j][b]]));
}
printf("%d %d\n",ans,pos);
return 0;
}
【BZOJ4149】[AMPPZ2014]Global Warming 单调栈+RMQ+二分的更多相关文章
- bzoj4149: [AMPPZ2014]Global Warming
头都烂了怎么头疼啊 考虑先做出对于一个位置以它作为唯一最小值的最远区间,这个可以单调栈上二分搞出来 那么对于一个位置这个区间而言,一定是选择这个区间的最大数是作为最终的唯一最大数最优的 为什么呢?我们 ...
- BZOJ1767/Gym207383I CEOI2009 Harbingers 斜率优化、可持久化单调栈、二分
传送门--BZOJCH 传送门--VJ 注:本题在BZOJ上是权限题,在Gym里面也不能直接看,所以只能在VJ上交了-- 不难考虑到这是一个\(dp\). 设\(dep_x\)表示\(x\)在树上的带 ...
- Bad Hair Day [POJ3250] [单调栈 或 二分+RMQ]
题意Farmer John的奶牛在风中凌乱了它们的发型……每只奶牛都有一个身高hi(1 ≤ hi ≤ 1,000,000,000),现在在这里有一排全部面向右方的奶牛,一共有N只(1 ≤ N ≤ 80 ...
- BZOJ.4540.[HNOI2016]序列(莫队/前缀和/线段树 单调栈 RMQ)
BZOJ 洛谷 ST表的一二维顺序一定要改过来. 改了就rank1了哈哈哈哈.自带小常数没办法. \(Description\) 给定长为\(n\)的序列\(A_i\).\(q\)次询问,每次给定\( ...
- HUID 5558 Alice's Classified Message 后缀数组+单调栈+二分
http://acm.hdu.edu.cn/showproblem.php?pid=5558 对于每个后缀suffix(i),想要在前面i - 1个suffix中找到一个pos,使得LCP最大.这样做 ...
- UVALive 6531 Go up the ultras 单调栈+RMQ
题目链接:点击打开链接 题意: 给定n座山 以下n个数字表示n座山的高度 若这座山u合法,则要满足: 1.若u的左边存在比u高的山,设v是u左边距离u近期的且严格比u高的山,在[v,u]之间至少有一座 ...
- The Preliminary Contest for ICPC Asia Xuzhou 2019 E XKC's basketball team [单调栈上二分]
也许更好的阅读体验 \(\mathcal{Description}\) 给n个数,与一个数m,求\(a_i\)右边最后一个至少比\(a_i\)大\(m\)的数与这个数之间有多少个数 \(2\leq n ...
- 【HNOI2016】序列 莫队+单调栈+RMQ
Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,ar-1,ar.若1≤l≤s≤t≤r≤n,则称a ...
- 51nod 1962区间计数(单调栈加二分)
题目要求是求出两个序列中处于相同位置区间并且最大值相同的区间个数,我们最直观的感受就是求出每个区间的最大值,这个可以O(N)的求,利用单调栈求出每个数作为最大值能够覆盖的区间. 然后我们可以在进行单调 ...
随机推荐
- HDU 5289 Assignment(多校2015 RMQ 单调(双端)队列)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289 Problem Description Tom owns a company and he is ...
- C# cs文件表头模版
设置位置:C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\ItemTemplatesCache\CSharp\Web\2 ...
- 批量改名的多种方法stu_3_finished.jpg 去掉finished,stu_{1..20}_finished.jpg
方法一:rename修改文件名 rename "finished" "" *.jpg [root@ob1 scripts]# rename "fini ...
- SQLSERVER2008中创建数据库发生无法获得数据库'model'上的排他锁
SQLSERVER2005中创建数据库发生无法获得数据库'model'上的排他锁是怎么回事? 创建数据库失败,提示无法获得数据库‘model’上的排他锁,如下图所示: 解决方法: 在查询分析器中运行如 ...
- 简单十招提高jQuery执行效率
1. 使用最新版本的jQuery jQuery的版本更新很快,你应该总是使用最新的版本.因为新版本会改进性能,还有很多新功能. 下面就来看看,不同版本的jQuery性能差异有多大.这里是三条最常见的j ...
- 数据库 Mysql内容补充二
多表查询 mysql支持的是SQL99标准的连接查询,并不支持oracle公司的外连接查询, 但是支持oracle等值查询,不等值查询,自连接查询,子查询(只要不是外连接(+)都支持) oracle也 ...
- jump display
查找了数据库,再在while里拼接成json是很麻烦的,所以,jump display 获得数组 <?php header("Content-Type:text/html; chars ...
- 控制反转是Spring框架的核心。
早在2004年,Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题.他总结出是依赖对象的获得被反转了.基于这个结论,他为控制反转创造了一个更好的名字:依赖注入.许多非凡的应用(比H ...
- 编译 & 执行 C++ 程序
编译 & 执行 C++ 程序接下来让我们看看如何把源代码保存在一个文件中,以及如何编译并运行它.下面是简单的步骤: 打开一个文本编辑器,添加上述代码.保存文件为 hello.cpp.打开命令提 ...
- linux -- ubuntu 通过命令行,设置文件及其子文件的权限
想一次修改某个目录下所有文件的权限,包括子目录中的文件权限也要修改,要使用参数-R表示启动递归处理. 例如: [root@localhost ~]# chmod 777 /home/user 注:仅把 ...