求助悬关,线段树20pts,代码有注释

P1253 扶苏的问题

liuenyin @ 2023-07-30 21:42:05

AC on #1 and #3,代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long INF=0x7ffffffffffffff;
struct segment_tree{
    struct node{
        ll l,r,w;//w: max
        ll lazytag_1,lazytag_2;//懒标记 
        node(){
            lazytag_1=lazytag_2=-INF;
        } 
    };
    node tree[4000005];//线段树开4倍空间
    ll arr[1000005];
    void build(int l,int r,int p){
        //   左  右   根
        tree[p].l=l;
        tree[p].r=r; 
        if(l==r){
            tree[p].w=arr[l];
            //arr为原数组 
            return;
        }
        int mid=(l+r)/2;
        build(l,mid,p*2);//建立左子树
        build(mid+1,r,p*2+1);//建立右子树
        tree[p].w=max(tree[p*2].w,tree[p*2+1].w);
    } 
    void pushdown_1(int p){
        //懒标记下传(opt=1) 即将区间内的值设为x 
        if(tree[p].lazytag_1!=-INF){
            tree[p*2].w = tree[p].lazytag_1;
            tree[p*2+1].w=tree[p].lazytag_1;
            tree[p*2].lazytag_1=tree[p].lazytag_1;
            tree[p*2+1].lazytag_1=tree[p].lazytag_1;
            tree[p].lazytag_1=-INF;
        } 
    }
    void pushdown_2(int p){
        //懒标记下传(opt=2) 即将区间内的值增加x
        if(tree[p].lazytag_2!=-INF){
            tree[p*2].w+=tree[p].lazytag_2;
            tree[p*2+1].w+=tree[p].lazytag_2;
            tree[p*2].lazytag_2+=tree[p].lazytag_2;
            tree[p*2+1].lazytag_2+=tree[p].lazytag_2;
            tree[p].lazytag_2=-INF;
        } 
    }
    void update_1(int l,int r,int p,int x){
        //更新区间的值(opt=1)
        if(l<=tree[p].l and r>=tree[p].r){
            tree[p].w=x;
            tree[p].lazytag_1=x;
            return;
        } 
        pushdown_1(p);
        int mid=(tree[p].l+tree[p].r)/2;
        if(l<=mid)update_1(l,r,p*2,x);
        if(r>mid)update_1(l,r,p*2+1,x);
        tree[p].w=max(tree[p*2].w,tree[p*2+1].w);
    }
    void update_2(int l,int r,int p,int x){
        //更新区间的值 (opt=2)
        if(l<=tree[p].l and r>=tree[p].r){
            tree[p].w+=x;
            tree[p].lazytag_2+=x;
            return;
        } 
        pushdown_2(p);
        int mid=(tree[p].l+tree[p].r)/2;
        if(l<=mid)update_2(l,r,p*2,x);
        if(r>mid)update_2(l,r,p*2+1,x);
        tree[p].w=max(tree[p*2].w,tree[p*2+1].w);
    }
    ll query(int l,int r,int p){
        //查询区间的值
        if(l<=tree[p].l and r>=tree[p].r){
            return tree[p].w;
        } 
    //  pushdown_1(p);
        pushdown_2(p);
        ll mid=(tree[p].l+tree[p].r)/2,ans=-INF;
        if(l<=mid)ans=max(ans,query(l,r,p*2));
        if(r>mid)ans=max(ans,query(l,r,p*2+1));
        return ans;
    }
};

segment_tree t;
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        scanf("%lld",&t.arr[i]);
    }
    t.build(1,n,1);
    int op,l,r,x;
    for(int i=1;i<=m;i++){
        cin>>op>>l>>r;
        //cout<<op<<" "<<l<<" "<<r<<endl;
        if(op==1||op==2)cin>>x; 
        if(op==1){
            t.update_1(l,r,1,x);
        }
        else if(op==2){
            t.update_2(l,r,1,x);
        }
        else{
            cout<<t.query(l,r,1)<<endl;
        }
    }
    return 0;
}

|