• BZOJ4355:Play with sequence——题解


    https://www.lydsy.com/JudgeOnline/problem.php?id=4355

    维护一个长度为N的序列a,现在有三种操作:
    1)给出参数U,V,C,将a[U],a[U+1],...,a[V-1],a[V]都赋值为C。
    2)给出参数U,V,C,对于区间[U,V]里的每个数i,将a[i]赋值为max(a[i]+C,0)。
    3)给出参数U,V,输出a[U],a[U+1],...,a[V-1],a[V]里值为0的数字个数。

    吉如一论文板子题(当然所有的操作都来自论文拼起来的那当然是板子了。)

    (本题解适合知道基本的吉司机线段树操作的人看。)

    1操作根据玄学势能分析如果当前区间数都相等的话就可以转换成加操作,如果不相等会变成相等。

    所以我们只要暴力做1操作(连lazy标记都不用打)即可。

    2操作拆成两个操作,一次是区间+c,一次是区间a[i]=max(a[i],0)。

    3操作实际就是问当前区间最小值为0时最小值个数。

    #include<map>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const ll INF=5e18;
    const int N=3e5+5;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    int n,m,b[N],cnt[N*4];
    ll mn[N*4],se[N*4],lzmn[N*4],lzad[N*4];
    inline void upt(int a){
        int ls=a<<1,rs=a<<1|1;
        if(mn[ls]==mn[rs]){
        mn[a]=mn[ls];se[a]=min(se[ls],se[rs]);
        cnt[a]=cnt[ls]+cnt[rs];
        }
        else if(mn[ls]<mn[rs]){
        mn[a]=mn[ls];se[a]=min(se[ls],mn[rs]);
        cnt[a]=cnt[ls];
        }else{
        mn[a]=mn[rs];se[a]=min(se[rs],mn[ls]);
        cnt[a]=cnt[rs];
        }
    }
    inline void pushadd(int a,ll x){
        mn[a]+=x;lzad[a]+=x;
        if(lzmn[a]!=-INF)lzmn[a]+=x;
        if(se[a]!=INF)se[a]+=x;
    }
    inline void push(int a){
        int ls=a<<1,rs=a<<1|1;
        if(lzad[a]){
        pushadd(ls,lzad[a]);
        pushadd(rs,lzad[a]);
        lzad[a]=0;
        }
        if(lzmn[a]!=-INF){
        if(mn[ls]<lzmn[a]){
               mn[ls]=lzmn[a];lzmn[ls]=lzmn[a];
        }
        if(mn[rs]<lzmn[a]){
                   mn[rs]=lzmn[a];lzmn[rs]=lzmn[a];
        }
        lzmn[a]=-INF;
        }
    }
    void build(int a,int l,int r){
        lzmn[a]=-INF;lzad[a]=0;
        if(l==r){
        mn[a]=b[l];se[a]=INF;cnt[a]=1;
        return;
        }
        int mid=(l+r)>>1;
        build(a<<1,l,mid);build(a<<1|1,mid+1,r);
        upt(a);
    }
    void add(int a,int l,int r,int l1,int r1,int x){
        if(r<l1||r1<l||(se[a]==INF&&mn[a]==0&&x<=0))return;
        if(l1<=l&&r<=r1){
        if(mn[a]+x>=0){
            pushadd(a,x);
            return;
        }
        else if(se[a]==INF||se[a]+x>0){
            pushadd(a,x);
            mn[a]=0;lzmn[a]=0;
            return;
        }
        }
        int mid=(l+r)>>1;
        push(a);
        add(a<<1,l,mid,l1,r1,x);add(a<<1|1,mid+1,r,l1,r1,x);
        upt(a);
    }
    void cover(int a,int l,int r,int l1,int r1,int x){
        if(r<l1||r1<l)return;
        if(l1<=l&&r<=r1&&se[a]==INF){
        pushadd(a,(ll)x-mn[a]);
        return;
        }
        int mid=(l+r)>>1;
        push(a);
        cover(a<<1,l,mid,l1,r1,x);cover(a<<1|1,mid+1,r,l1,r1,x);
        upt(a);
    }
    int qry(int a,int l,int r,int l1,int r1){
        if(r<l1||r1<l)return 0;
        if(l1<=l&&r<=r1){
        if(!mn[a])return cnt[a];
        return 0;
        }
        int mid=(l+r)>>1;
        push(a);
        return qry(a<<1,l,mid,l1,r1)+qry(a<<1|1,mid+1,r,l1,r1);
    }
    int main(){
        n=read(),m=read();
        for(int i=1;i<=n;i++)b[i]=read();
        build(1,1,n);
        while(m--){
        int op=read(),x=read(),y=read();
        if(op==1)cover(1,1,n,x,y,read());
        if(op==2)add(1,1,n,x,y,read());
        if(op==3)printf("%d
    ",qry(1,1,n,x,y));
        }
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

     +本文作者:luyouqi233。               +

     +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    Prometheus监控神器-服务发现篇(二)
    Prometheus监控神器-服务发现篇(一)
    Prometheus监控神器-Alertmanager篇(4)
    Prometheus监控神器-Alertmanager篇(3)
    Prometheus监控神器-Rules篇
    Linux内核分析——字符集总结与分析
    Linux内核分析——ELF文件格式分析
    Linux内核分析——程序破解
    Linux内核学习总结
    《Linux内核设计与实现》课本第四章学习总结
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/9155814.html
Copyright © 2020-2023  润新知