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\n",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;
}

 

posted @ 2019-01-12 10:28  AKCqhzdy  阅读(163)  评论(0编辑  收藏  举报