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的更多相关文章
随机推荐
- 【HDOJ5447】Good Numbers(数论)
			题意: 思路:From https://blog.csdn.net/qq_36553623/article/details/76683438 大概就是把1e6里面的质因子能除的都除光之后借助两者gcd ... 
- SpringBoot启动时的Banner设置
			Spring Boot程序启动的时候输出的由字符组成的Spring符号并不陌生.这个是Spring Boot为自己设计的Banner: 1. 第一种方式:修改的时候,进行设置,在Application ... 
- legend3---lavarel常用artisan命令操作
			legend3---lavarel常用artisan命令操作 一.总结 一句话总结: 帮助:php artisan可以调出帮助命令 1.npm安装后盾js? npm install hdjs node ... 
- Mybaits 分页插件应用
			mybaits 分页插件省去了很多麻烦,接下来介绍如果应用分页插件 1.首先导入pagehelper.jar和jsplparser 2 在mybaits.xml中配置 <plugins> ... 
- cors 预请求
			1.CORS的其他限制 默认允许的方法只有:GET.HEAD.POST默认允许的Content-Type:text/plain.multipart/form-data.applicaton/x-www ... 
- React组件库集锦及学习视频
			[转载]https://www.rails365.net/articles/react-zui-hao-de-ui-zu-jian-ku-ji-jin 这里有一篇讨论,说了哪个才是 React 最好的 ... 
- KNN距离函数的简单拓展
			KNN--k-NearestNeighbor可以是是分类法中最简单的算法了. 大致的idea为:找出k各跟新数据点最像的点,看这些点主要属于哪类,那么新数据点也就属于哪类的了. 其伪代码如下: 1. ... 
- [flask]jina2处理表单--实现搜索功能
			思路: 获取查询关键字 查询数据库,获得查询结果 将查询结果返回模板文件 forms.py from flask_wtf import FlaskForm from wtforms import S ... 
- [VBA]利用正则表达式创建函数处理字符串
			1.去除字符串中的数字 Function aa(sr As Range)Set reg = CreateObject("vbscript.regexp")With reg.Glob ... 
- Selenium 2自动化测试实战14(定位一组元素)
			一.定位一组元素 WebDriver还提供了与前面所对应的8钟用于定位一组元素的方法.定位一组元素的方法与定位单个元素的方法类似,唯一的区别是在单词element后面多了一个S表示复数.定位一组元素一 ... 
