P4314 CPU监控

【题意】

维护一个数据结构支持如下操作:

1.查询当前的区间最大值

2.查询历史上区间最大值

3.区间加 4.区间覆盖

【分析】

这道题目是历史版本维护的一个经典题目

我们记录一个点的tag(x,y)表示先加上x,再与y取max,得到的这个点表示的区间的值

我们为了维护历史的最大值,所以要维护一个maxval和maxtag

两个tag取max,即x和y同时取max

两个tag求和,x就是两个相加,y得讨论,可能第一个覆盖+第二个,也可能是直接覆盖第二个大,取个max即可

然后我们只需要利用这些信息取维护即可

 

【代码】

#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define fi first
#define se second
#define lson now<<1
#define rson now<<1|1
typedef long long ll;
const int maxn=1e5+5;
const ll inf=1e17;
int n,m;
struct seg
{
    ll nowval,lastval;
}tr[maxn<<2];
struct tag
{
    ll x,y;
    void clear()
    {
        x=0; y=-inf;
    }
    ll calc(ll v)
    {
        return max(v+x,y);
    }
}t[maxn<<2],maxt[maxn<<2];
ll v[maxn];
tag max(tag x,tag y)
{
    return (tag){max(x.x,y.x),max(x.y,y.y)};
}
tag operator + (tag x,tag y)
{
    return (tag){max(-inf,x.x+y.x),max(x.y+y.x,y.y)};
}
void pushup(int now)
{
    tr[now].nowval=max(tr[lson].nowval,tr[rson].nowval);
    tr[now].lastval=max(tr[lson].lastval,tr[rson].lastval);
}
void pushtag(int now,tag x,tag y)
{
    maxt[now]=max(maxt[now],t[now]+y);
    t[now]=t[now]+x;
    tr[now].lastval=max(tr[now].lastval,y.calc(tr[now].nowval));
    tr[now].nowval=x.calc(tr[now].nowval);
}
void pushdown(int now)
{
    pushtag(lson,t[now],maxt[now]);
    pushtag(rson,t[now],maxt[now]);
    t[now].clear(); maxt[now].clear();
}
void build(int now,int l,int r)
{
    t[now].clear(); maxt[now].clear();
    if(l==r)
    {
        tr[now].lastval=tr[now].nowval=v[l];
        return;
    }
    int mid=(l+r)>>1;
    build(lson,l,mid);
    build(rson,mid+1,r);
    pushup(now);
}
void update(int now,int l,int r,int L,int R,tag val)
{
    if(l>=L && r<=R)
    {
        pushtag(now,val,val);
        return;
    }
    int mid=(l+r)>>1;
    pushdown(now);
    if(L<=mid) update(lson,l,mid,L,R,val);
    if(mid<R) update(rson,mid+1,r,L,R,val);
    pushup(now);
}
ll query(int now,int l,int r,int L,int R,int op)
{
    if(l>=L && r<=R)
        return op==1?tr[now].nowval:tr[now].lastval;
    int mid=(l+r)>>1;
    pushdown(now);
    if(R<=mid) return query(lson,l,mid,L,R,op);
    if(L>mid) return query(rson,mid+1,r,L,R,op);
    return max(query(lson,l,mid,L,R,op),query(rson,mid+1,r,L,R,op));
}
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&v[i]);
    scanf("%d",&m);
    char c[5];
    build(1,1,n);
    int x,y;
    for(int i=1;i<=m;i++)
    {
        scanf("%s",c); scanf("%d%d",&x,&y);
        tag tmp; tmp.x=tmp.y=-inf;
        if(c[0]=='Q') printf("%lld\n",query(1,1,n,x,y,1));
        if(c[0]=='A') printf("%lld\n",query(1,1,n,x,y,0));
        if(c[0]=='P') scanf("%lld",&tmp.x),update(1,1,n,x,y,tmp);
        if(c[0]=='C') scanf("%lld",&tmp.y),update(1,1,n,x,y,tmp);
    }
    return 0;
}

 

posted @ 2021-05-31 17:01  andyc_03  阅读(100)  评论(0)    收藏  举报