• cf1108E2 线段树类似扫描线


    /*
    有点像扫描线 
    思路:从左到右枚举每个点,枚举到点i时,把所有以i为起点的区间的影响删去
    再加上以i-1为结尾的区间的影响 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 200005
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    int n,m,a[maxn];
    struct Inv{int l,r;}p[400];
    
    int lazy[maxn<<2],Min[maxn<<2];
    inline void pushup(int rt){
        Min[rt]=min(Min[rt<<1],Min[rt<<1|1]);
    }
    inline void pushdown(int rt){
        if(lazy[rt]){
            lazy[rt<<1]+=lazy[rt];lazy[rt<<1|1]+=lazy[rt];
            Min[rt<<1]+=lazy[rt];Min[rt<<1|1]+=lazy[rt];
            lazy[rt]=0; 
        }
    }
    void build(int l,int r,int rt){
        lazy[rt]=0;
        if(l==r){Min[rt]=a[l];return;}
        int m=l+r>>1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    void update(int L,int R,int l,int r,int rt,int val){
        if(L<=l && R>=r){
            Min[rt]+=val,lazy[rt]+=val;return;
        }
        pushdown(rt);
        int m=l+r>>1;
        if(L<=m)update(L,R,lson,val);
        if(R>m)update(L,R,rson,val);
        pushup(rt);
    }
    int query(int L,int R,int l,int r,int rt){
        if(L<=l&&R>=r){return Min[rt];}
        pushdown(rt);
        int m=l+r>>1,res=99999999;
        if(L<=m)res=min(res,query(L,R,lson));
        if(R>m)res=min(res,query(L,R,rson));
        pushup(rt);
        return res;
    }
    
    vector<int>ans[100005];
    int main(){
        cin>>n>>m;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=m;i++)scanf("%d%d",&p[i].l,&p[i].r);    
        
        int Max=-1,index=0;
        build(1,n,1);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(p[j].l<=i&&p[j].r>=i){//该区间和当前坐标有关 
                    if(i!=1 && !(p[j].l<=i-1&&p[j].r>=i-1))//和左边结点无关
                        update(p[j].l,p[j].r,1,n,1,1);//加上这段的值 
                    continue; 
                }
                ans[i].push_back(j);
                //算上之前没算上的区间 
                if(i==1 || p[j].l<=i-1&&p[j].r>=i-1)
                    update(p[j].l,p[j].r,1,n,1,-1); 
            }
            
            int tmp=query(1,n,1,n,1);
            if(a[i]-tmp>Max){index=i;Max=a[i]-tmp;}
        }
        cout << Max << endl;
        cout << ans[index].size()<<endl;
        for(int i=0;i<ans[index].size();i++)
            cout << ans[index][i]<< " ";
        
    } 
  • 相关阅读:
    用dockerFile和docker build命令 创建带两个数据卷的新镜像
    Docker 学习 3 镜像更多命令 docker commit 提交容器副本,使之成为一个新的镜像
    Docker学习笔记 2 更多的容器命令
    Docker的学习1 安装 与 基础篇
    SeekBar(拖动条)
    本周总结
    ProgressBar(进度条)
    Android对话框
    css语法
    css基础
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10358094.html
Copyright © 2020-2023  润新知