10分,样例没过,求调!!

P1253 扶苏的问题

2022_37_yzyUUU @ 2024-02-17 18:57:48

#include <bits/stdc++.h>
#define void inline void
#define int long long
#define N 100005
using namespace std;

int a[N],l[4*N],r[4*N],ma[4*N],cag_tag[4*N],add_tag[4*N],n,q;

void build(int p,int nl,int nr){
    l[p]=nl,r[p]=nr;
    if(nl==nr){
        ma[p]=a[nl];
        return;
    }
    int mid=nl+nr>>1;
    build(p<<1,nl,mid);
    build(p<<1|1,mid+1,nr);
    ma[p]=max(ma[p<<1],ma[p<<1|1]);
}

void down_add(int p){
    if(add_tag[p]){
        ma[p<<1]+=add_tag[p];
        ma[p<<1|1]+=add_tag[p];
        add_tag[p<<1]+=p;
        add_tag[p<<1|1]+=p;
        add_tag[p]=0;
    }
}

void down_cag(int p){
    if(cag_tag[p]){
        ma[p<<1]=cag_tag[p];
        ma[p<<1|1]=cag_tag[p];
        cag_tag[p<<1]=p;
        cag_tag[p<<1|1]=p;
        cag_tag[p]=0;
    }
}

void add(int p,int gl,int gr,int x){
    if(gl<=l[p]&&r[p]<=gr){
        add_tag[p]+=x;
        ma[p]+=x;
        return;
    }
    down_cag(p);
    down_add(p);
    int mid=l[p]+r[p]>>1;
    if(gl<=mid)add(p<<1,gl,gr,x);
    if(gr>mid)add(p<<1|1,gl,gr,x);
    ma[p]=max(ma[p<<1],ma[p<<1|1]);
}

void change(int p,int gl,int gr,int x){
    if(gl<=l[p]&&r[p]<=gr){
        add_tag[p]=x;
        ma[p]=x;
        return;
    }
    down_cag(p);
    down_add(p);
    int mid=l[p]+r[p]>>1;
    if(gl<=mid)change(p<<1,gl,gr,x);
    if(gr>mid)change(p<<1|1,gl,gr,x);
    ma[p]=max(ma[p<<1],ma[p<<1|1]);
}

int ask(int p,int gl,int gr){
    if(gl<=l[p]&&r[p]<=gr){
        return ma[p];
    }
    down_cag(p);
    down_add(p);
    int mid=l[p]+r[p]>>1,ans1=INT_MIN,ans2=INT_MIN;
    if(gl<=mid)ans1=max(ans1,ask(p<<1,gl,gr));
    if(gr>mid)ans2=max(ans2,ask(p<<1|1,gl,gr));
    return max(ans1,ans2);
}

signed main() {
    cin>>n>>q;
    for(int i=1;i<=n;i++)cin>>a[i];
    build(1,1,n);
    for(int i=1;i<=q;i++){
        int op,l,r,x;
        cin>>op>>l>>r;
        if(op==1){
            cin>>x;
            change(1,l,r,x);
        }
        if(op==2){
            cin>>x;
            add(1,l,r,x);
        }
        if(op==3)
            cout<<ask(1,l,r)<<"\n";
    }
}

by 杜都督 @ 2024-02-17 19:25:06

这道题的懒惰标记不能这么处理

根据逻辑可以推断出修改标记和增加标记不会同时出现

因为当执行增加操作时,若节点已有修改标记,则直接将修改标记增加对应的值即可,无须改动增加标记,否则再改动增加标记

而当执行修改操作时,需将增加标记清空

所以你需要修正一下添加和下传懒惰标记的逻辑


|