【BZOJ4149】[AMPPZ2014]Global Warming

Description

给定一个序列a[1],a[2],...,a[n]。请从中选出一段连续子序列,使得该区间最小值唯一、最大值也唯一。
输出选出的子序列的长度的最大值以及取到最大值时左端点的最小值。

Input

第一行包含一个正整数n(1<=n<=500000),表示序列长度。
第二行包含n个正整数,依次表示a[1],a[2],...,a[n](-10^9<=a[i]<=10^9)。

Output

包含一行两个整数l,k,其中l表示选出的子序列的长度的最大值,k表示取到最大值时左端点的最小值。

Sample Input

10
8 3 2 5 2 3 4 6 3 6

Sample Output

6 4

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+二分的更多相关文章

  1. bzoj4149: [AMPPZ2014]Global Warming

    头都烂了怎么头疼啊 考虑先做出对于一个位置以它作为唯一最小值的最远区间,这个可以单调栈上二分搞出来 那么对于一个位置这个区间而言,一定是选择这个区间的最大数是作为最终的唯一最大数最优的 为什么呢?我们 ...

  2. BZOJ1767/Gym207383I CEOI2009 Harbingers 斜率优化、可持久化单调栈、二分

    传送门--BZOJCH 传送门--VJ 注:本题在BZOJ上是权限题,在Gym里面也不能直接看,所以只能在VJ上交了-- 不难考虑到这是一个\(dp\). 设\(dep_x\)表示\(x\)在树上的带 ...

  3. Bad Hair Day [POJ3250] [单调栈 或 二分+RMQ]

    题意Farmer John的奶牛在风中凌乱了它们的发型……每只奶牛都有一个身高hi(1 ≤ hi ≤ 1,000,000,000),现在在这里有一排全部面向右方的奶牛,一共有N只(1 ≤ N ≤ 80 ...

  4. BZOJ.4540.[HNOI2016]序列(莫队/前缀和/线段树 单调栈 RMQ)

    BZOJ 洛谷 ST表的一二维顺序一定要改过来. 改了就rank1了哈哈哈哈.自带小常数没办法. \(Description\) 给定长为\(n\)的序列\(A_i\).\(q\)次询问,每次给定\( ...

  5. HUID 5558 Alice's Classified Message 后缀数组+单调栈+二分

    http://acm.hdu.edu.cn/showproblem.php?pid=5558 对于每个后缀suffix(i),想要在前面i - 1个suffix中找到一个pos,使得LCP最大.这样做 ...

  6. UVALive 6531 Go up the ultras 单调栈+RMQ

    题目链接:点击打开链接 题意: 给定n座山 以下n个数字表示n座山的高度 若这座山u合法,则要满足: 1.若u的左边存在比u高的山,设v是u左边距离u近期的且严格比u高的山,在[v,u]之间至少有一座 ...

  7. 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 ...

  8. 【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 ...

  9. 51nod 1962区间计数(单调栈加二分)

    题目要求是求出两个序列中处于相同位置区间并且最大值相同的区间个数,我们最直观的感受就是求出每个区间的最大值,这个可以O(N)的求,利用单调栈求出每个数作为最大值能够覆盖的区间. 然后我们可以在进行单调 ...

随机推荐

  1. MVC教程一:MVC简介

    一.概述 1.MVC是一种流行的Web应用架构技术,他把Web应用划分成Model(模型).Controller(控制器)和View(视图)三部分. 2.优点:可测试.可维护 3.MVC是ASP.NE ...

  2. java-pageEncoding与contentType的区别

    pageEncoding是jsp文件本身的编码 contentType的charset是指服务器发送给客户端时的内容编码 JSP要经过两次的“编码”,第一阶段会用pageEncoding,第二阶段会用 ...

  3. Rails NameError uninitialized constant class solution

    rails nameerror uninitialized constant class will occur if your rails console is not loaded with con ...

  4. 可供前端工程师选择的精彩CSS框架

    在这里你有一个很酷的框架,收集创建的CSS布局. 如果你不喜欢框架,宁愿使用自己的手写代码以促进自己的发展,请跳过本篇文章. 我想有一个建设性的意见,那就是有选择的使用其优点避开其缺点. 就个人而言, ...

  5. 不可错过的10个超棒jQuery表单操作代码片段

    jQuery 绝对是一个伟大的开源javascript类库,是帮助我们快速和高效开发前端应用的利器.可能大家在日常的开发过程中常常会处理表单相关的 javascript,在今天这篇代码片段分享文章中, ...

  6. [oracle] 系统权限管理

    1 利用超级用户连接到数据库登录 sqlplus / as sysdba or slqplus SYS/SYSPWD as sysdba 这两个命令的效果是一样的,都是以sysdba的身份使得SYS管 ...

  7. 双卡手机怎么指定SIM卡打电话

    双卡手机如何指定SIM卡打电话 package com.example.dualsimtest; import android.app.Activity; import android.content ...

  8. IOS 命令行编译

    转自:简书 IOS 命令行编译   发表于 IOS2013-08-17 07:07 字数: 583 阅读量: 61 This document will note about the ios comm ...

  9. VMware Host Agent服务不能正常启动

    VMware Host Agent服务不能正常启动 原因及解决方法 一直都在用VMWare Server 2.0,其他都还好,就是隔三差五的会有些小问题,比如VMware Host Agent服务不能 ...

  10. 【Graphlab】

    https://dato.com/ graphlab