【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;
}

转载于:https://www.cnblogs.com/CQzhangyu/p/7898534.html

【BZOJ4149】[AMPPZ2014]Global Warming 单调栈+RMQ+二分相关推荐

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

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

  2. 经典算法题:字典树、并查集、单调栈、二分、带标记函数dp、树、全排列、字符串问题等常用算法

    0. Tips 1. 位运算 如何枚举一个二进制状态数字k的子集, 方法就是针对中的二进制为1的位开始进行减法,判断数字k的二进制子集, 像枚举(2^k-1) ~ 0一样枚举其子集: int sub ...

  3. Loj#2880-「JOISC 2014 Day3」稻草人【CDQ分治,单调栈,二分】

    正题 题目链接:https://loj.ac/problem/2880 题目大意 给出平面上的nnn个点,然后求有多少个矩形满足 左下角和右上角各有一个点 矩形之间没有其他点 1≤n≤2×105,1≤ ...

  4. 后缀数组 ---- 2018~2019icpc焦作H题[后缀数组+st表+二分+单调栈]

    题目链接 题目大意: 给出nnn个数,定义f[l,r]f[l,r]f[l,r]表示 区间[l,r][l,r][l,r]的最大值,求所有 子区间的最大值的和,要求相同的子区间只能算一次 比如数列 5 6 ...

  5. 【bzoj3879】SvT 后缀数组+倍增RMQ+单调栈

    题目描述 (我并不想告诉你题目名字是什么鬼) 有一个长度为n的仅包含小写字母的字符串S,下标范围为[1,n]. 现在有若干组询问,对于每一个询问,我们给出若干个后缀(以其在S中出现的起始位置来表示), ...

  6. 【计蒜客 - 2019南昌邀请赛网络赛 - I】Max answer(单调栈,RMQ)

    题干: Alice has a magic array. She suggests that the value of a interval is equal to the sum of the va ...

  7. 【Codeforces549F】Yura and Developers [单调栈][二分]

    Yura and Developers Time Limit: 20 Sec  Memory Limit: 512 MB Description Input Output Sample Input 4 ...

  8. bzoj 4237: 稻草人(CDQ分治+单调栈+二分)

    4237: 稻草人 Time Limit: 40 Sec  Memory Limit: 256 MB Submit: 1352  Solved: 594 [Submit][Status][Discus ...

  9. 【Codeforces 549F】Yura and Developers | 单调栈、启发式合并、二分

    题目链接:https://codeforces.com/problemset/problem/549/F 题目大意: 给定一个序列和一个mod值,定义[l,r]合法当l到r的所有元素和减去其中的最大值 ...

  10. BZOJ 2388--旅行规划(分块单调栈二分)

    2388: 旅行规划 Time Limit: 50 Sec  Memory Limit: 128 MB Submit: 405  Solved: 118 [Submit][Status][Discus ...

最新文章

  1. AC日记——传染病控制 洛谷 P1041
  2. 基于树莓派上的小电台
  3. Redis-序列化和存储模式
  4. 为朋友写的一个投票功能的提交代码
  5. python写一个文件下载器_python使用tcp实现一个简单的下载器
  6. 新手入门Web前端,你需要克服这几点困难
  7. 沙老师的作业系列——Crudd‘s Crack Head
  8. ant vue 设置中文_Ant Design Vue 添加区分中英文的长度校验功能
  9. sh.k7p.work/index.php,Laowang's Blogs
  10. guid java_JAVA实现生成GUID的方法
  11. mvc ajax post json数据,springmvc解决ajax post json格式数据的跨域问题
  12. 关于Timestamp的valueOf()方法
  13. 在c#使用Windows IOCP(完成端口)编程研究
  14. (转)Fintech路上券商究竟做错了什么?漏做了什么?
  15. 多电压等级计算机潮流计算,电力系统潮流计算
  16. 尚学堂马士兵servlet/JSP笔记(一、Http协议及WebApp初步)
  17. Markdown 图片居中并添加标题
  18. 谈谈用户体验与风控的平衡性
  19. 单精度浮点数和双精度浮点数有什么区别
  20. 兼容微信6.74 ios12版本

热门文章

  1. 操作系统原理(六)设备管理
  2. git学习中遇到的疑难杂症
  3. 345. Reverse Vowels of a String【easy】
  4. null value in entry: destinationDir=null
  5. chrome浏览器爬虫WebDriverException解决采用python + selenium + chrome + headless模式
  6. [POJ3580]SuperMemo
  7. hibernate笔记4--qbc查询
  8. 网络对抗——web基础
  9. Oracle数据导入导出imp/exp sp2-0734:未知的命令开头'imp...解决方法
  10. ASP.NET 推荐书籍