Codeforces6E_Exposition
题意
给定一个序列,求有多少个最长连续子序列满足最大值减最小值之差不超过\(k\)。
分析
- 跟序列最大值最小值有关的可以想到单调栈,先预处理出每个数作为最大值能延伸的区间,然后枚举每个数作为最大值。
- 最大的满足条件的连续序列显然左边就是要在\([le[i],i-1]\)里找到大于等于\(a[i]-k\)的最小值对应的下标,右边同理。
- 线段树维护区间最小值,然后再套一个二分(应该也可以不用,就一个log,不过二分容易想),求出两端能满足条件的序列端点,计算出长度更新答案。
代码
#include <bits/stdc++.h>
using namespace std;
#define ls i<<1
#define rs i<<1|1
#define mid (l+r)/2
const int N=1e5+50;
int n,k,a[N];
int le[N],ri[N];
int mn[N*4];
void build(int i,int l,int r){
if(l==r){
mn[i]=a[l];
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
mn[i]=min(mn[ls],mn[rs]);
}
int query(int i,int l,int r,int ql,int qr){
if(ql<=l && qr>=r){
return mn[i];
}
int ans=0x3f3f3f3f;
if(ql<=mid){
ans=min(ans,query(ls,l,mid,ql,qr));
}
if(qr>mid){
ans=min(ans,query(rs,mid+1,r,ql,qr));
}
return ans;
}
set<pair<int,int> > res;
int mx;
int main(){
// freopen("in.txt","r",stdin);
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
stack<int> s;
for(int i=1;i<=n;i++){
while(!s.empty() && a[s.top()]<=a[i]){
s.pop();
}
if(s.empty()){
le[i]=1;
}else{
le[i]=s.top()+1;
}
s.push(i);
}
while(!s.empty()){
s.pop();
}
for(int i=n;i>=1;i--){
while(!s.empty() && a[s.top()]<=a[i]){
s.pop();
}
if(s.empty()){
ri[i]=n;
}else{
ri[i]=s.top()-1;
}
s.push(i);
}
build(1,1,n);
for(int i=1;i<=n;i++){
int t=a[i]-k;
//查询[le[i],i-1] >=t 的最小值的值和位置
int L=le[i],R=i-1;
int lidx=i;
while(L<=R){
int M=(L+R)/2;
int tm=query(1,1,n,M,i-1);
if(tm>=t){
lidx=M;
R=M-1;
}else{
L=M+1;
}
}
L=i+1,R=ri[i];
int ridx=i;
while(L<=R){
int M=(L+R)/2;
int tm=query(1,1,n,i+1,M);
if(tm>=t){
ridx=M;
L=M+1;
}else{
R=M-1;
}
}
int ans=ridx-lidx+1;
if(ans>mx){
mx=ans;
res.clear();
res.insert({lidx,ridx});
}else if(ans==mx){
res.insert({lidx,ridx});
}
}
int siz=res.size();
printf("%d %d\n",mx,siz);
for(auto it:res){
printf("%d %d\n",it.first,it.second);
}
return 0;
}
Codeforces6E_Exposition的更多相关文章
随机推荐
- echarts 有关饼形图和map的使用技巧1(饼图)
http://blog.csdn.net/yhn1121/article/details/52041742 先上个链接,百度无意间搜到的,写得比我全面,可以直接飞去看它: 之前写网页用过echarts ...
- python学习之路(2)(渗透信息收集)
scapy的用法 通过目标ip的回复判断目标ip主机的情况 先写上三层的IP 四层的TCP 然后r.display看一下我们的包 src是源ip dst是目标ip 我们添加目标ip 这里是网关的ip ...
- [Java]将算术表达式(中序表达式Infix)转成后续表达式Postfix
Inlet类: package com.hy; import java.io.BufferedReader; import java.io.IOException; import java.io.In ...
- 深度学习----现今主流GAN原理总结及对比
原文地址:https://blog.csdn.net/Sakura55/article/details/81514828 1.GAN 先来看看公式: GAN网络主要由两个网络构 ...
- Activity 的状态都有哪些?
a) foreground activityb) visible activityc) background activityd) empty process
- 什么是 ANR 如何避免它?
在 Android 上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application Not Responding)对话框.用户可以 ...
- 直连网(directly-connected networks)个数的计算
直连网分为两种,point-to-point link和multiple access link, 如图: 对一个网络数直连网个数时,以上两种link都要计算.例子如下: 1. How many di ...
- Docker环境安装部署Java应用(含安装Tomcat和JDK)
1.部署思路 两台docker机(centos 7系统),Docker 版本:18.09.6, build 481bc77156 Docker host IP:192.168.102.135 Dock ...
- 阶段3 2.Spring_08.面向切面编程 AOP_9 spring基于注解的AOP配置
复制依赖和改jar包方式 src下的都复制过来. 复制到新项目里了 bean.xml里面复制上面一行代码到下面.把aop改成context. 配置spring容器创建时要扫描的包 Service的配置 ...
- 如何利用Nginx的缓冲、缓存优化提升性能
使用缓冲释放后端服务器 反向代理的一个问题是代理大量用户时会增加服务器进程的性能冲击影响.在大多数情况下,可以很大程度上能通过利用Nginx的缓冲和缓存功能减轻. 当代理到另一台服务器,两个不同的连接 ...