• bzoj3064: Tyvj 1518 CPU监控


    填坑计划。。。

    这是历史最值线段树的裸蹄,考察的也就是对打(xjb)标(tao)记(lun)的应用,也就是merge函数

    考虑在维护最大值的基础上记录历史最值,以及一个历史最值懒标记

    假设这个懒标记为二元组(add,cover)表示历史最值是当前的最大值(未下放最大值的懒标记)加上add,或就是cover,反正保证的是先加再覆盖,和最大值的懒标记刚好反过来,是为了合并方便

    那么对于只cover的那相当于加0再cover咯

    标记的下放,设当前为1,有(add1,cover1)+(add2,cover2)=(add1,max(cover1,cover2,lastcover+add2))注意这里add2加的是当前未下发标记时最后一次覆盖的值

    还有一种特殊情况,就是当前还没有覆盖过,此时(add1,cover1)+(add2,cover2)=(max(add1,lastadd+add2),cover2)

    非常值得注意的是,关于last的东西都是靠最大值的懒标记得来的,我打懒标记是cover的时候顺便清空add,假如add和cover均有值说明add是在cover之后,那么对lastcover是cover+add的

    还有就是初始设为-inf的cover是有可以+一个乱七八糟的东西然后和另一个-inf比较更新历史懒标记的。。。。假如你打==-inf的话就会调成sb了。。。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    
    #define mid (ql+qr)/2
    #define lc now<<1
    #define rc now<<1|1
    using namespace std;
    const int inf=(1<<30);
    
    struct pa
    {
        int ad,cv;
        pa(){ad=0,cv=-inf;} void clear(){ad=0,cv=-inf;}
        pa(int AD,int CV){ad=AD,cv=CV;}
    };int a[110000];
    //~~~~~~~~~~~tab~~~~~~~~~~~~~~~~~~
    
    struct node
    {
        int mx; pa la; //only use for now 
        int hmx; pa ha; //only use for history 
        
        pa merge(pa ne)
        {
            if(ha.cv==-inf)ha=pa(max(ha.ad,la.ad+ne.ad),ne.cv);
            else ha=pa(ha.ad,max(la.ad+la.cv+ne.ad*(la.cv!=-inf),max(ha.cv,ne.cv)));
        }
    }tr[310000];
    
    void pushdown(int now)
    {
        pa h=tr[now].ha,l=tr[now].la;
        tr[now].ha.clear(),tr[now].la.clear();
        if(lc!=0)
        {
            tr[lc].hmx=max(tr[lc].hmx,max(tr[lc].mx+h.ad,h.cv));
            tr[lc].merge(h);
            
            if(l.cv!=-inf)
                tr[lc].mx=l.cv,
                    tr[lc].la.cv=l.cv,tr[lc].la.ad=0;
            tr[lc].mx+=l.ad;
            tr[lc].la.ad+=l.ad;
        }
        if(rc!=0)
        {
            tr[rc].hmx=max(tr[rc].hmx,max(tr[rc].mx+h.ad,h.cv));
            tr[rc].merge(h);
            
            if(l.cv!=-inf)
                tr[rc].mx=l.cv,
                    tr[rc].la.cv=l.cv,tr[rc].la.ad=0;
            tr[rc].mx+=l.ad;
            tr[rc].la.ad+=l.ad;
        }
    }
    void update(int now)
    {
        tr[now].mx=max(tr[lc].mx,tr[rc].mx);
        tr[now].hmx=max(tr[lc].hmx,tr[rc].hmx);
    }
    //~~~~~~~~~~~~~~in~~~~~~~~~~~~~~~~~~~
    
    void bt(int now,int ql,int qr)
    {
        if(ql==qr)
            tr[now].mx=tr[now].hmx=a[ql];
        else 
            bt(lc,ql,mid),bt(rc,mid+1,qr),
                update(now);
    }
    void add(int now,int ql,int qr,int l,int r,int d)
    {
        if(ql==l&&qr==r)
        {
            tr[now].merge(pa(d,-inf));
            tr[now].mx+=d;
            tr[now].la.ad+=d;
            tr[now].hmx=max(tr[now].hmx,tr[now].mx);
            return ;
        }
        pushdown(now);
             if(r<=mid)  add(lc,ql,mid,l,r,d);
        else if(mid+1<=l)add(rc,mid+1,qr,l,r,d);
        else add(lc,ql,mid,l,mid,d),add(rc,mid+1,qr,mid+1,r,d);
        update(now);
    }
    void change(int now,int ql,int qr,int l,int r,int d)
    {
        if(ql==l&&qr==r)
        {
            tr[now].merge(pa(0,d));
            tr[now].mx=d;
            tr[now].la.cv=d,tr[now].la.ad=0;
            tr[now].hmx=max(tr[now].hmx,tr[now].mx);
            return ;
        }
        pushdown(now);
             if(r<=mid)  change(lc,ql,mid,l,r,d);
        else if(mid+1<=l)change(rc,mid+1,qr,l,r,d);
        else change(lc,ql,mid,l,mid,d),change(rc,mid+1,qr,mid+1,r,d);
        update(now);
    }
    //.......change........
    int findmax(int now,int ql,int qr,int l,int r,bool op)
    {
        if(ql==l&&qr==r)return op==1?tr[now].mx:tr[now].hmx;
        pushdown(now);
             if(r<=mid)  return findmax(lc,ql,mid,l,r,op);
        else if(mid+1<=l)return findmax(rc,mid+1,qr,l,r,op);
        else return max(findmax(lc,ql,mid,l,mid,op),findmax(rc,mid+1,qr,mid+1,r,op));
    }
    //........getans......
    //~~~~~~~~~~~~~~~out~~~~~~~~~~~~~~~~~~~~~~
    
    char ss[5];
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        bt(1,1,n);
        
        int Q,x,y,d;
        scanf("%d",&Q);
        while(Q--)
        {
            scanf("%s",ss+1);
            if(ss[1]=='Q'||ss[1]=='A')
            {
                scanf("%d%d",&x,&y);
                printf("%d
    ",findmax(1,1,n,x,y,ss[1]=='Q'));
            }
            else
            {
                scanf("%d%d%d",&x,&y,&d);
                if(ss[1]=='P')add(1,1,n,x,y,d);
                else change(1,1,n,x,y,d);
            }
        }
        
        return 0;
    }
  • 相关阅读:
    生日蜡烛——第七届蓝桥杯C语言B组(省赛)第二题
    积分之谜——第六届蓝桥杯C语言B组(国赛)第一题
    平方十位数——第八届蓝桥杯JavaB组(国赛)第一题
    激光样式——第九届蓝桥杯C语言B组(国赛)第二题
    换零钞——第九届蓝桥杯C语言B组(国赛)第一题
    煤球数目——第七届蓝桥杯C语言B组(省赛)第一题
    扫描算法(SCAN)——磁盘调度管理
    最短寻道优先算法(SSTF)——磁盘调度管理
    最近最少使用算法(LRU)——页面置换
    ssm返回jsonp数据格式
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10258888.html
Copyright © 2020-2023  润新知