线段树求调,60分

P1253 扶苏的问题

array2022 @ 2024-07-08 11:19:43

在本地试了一下,输入:

6 3
1 1 4 5 1 4
1 1 6 -100
3 1 6
3 1 5

那么会输出:

-100
0

我搞不明白是怎么回事,代码如下。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct node{
    int l,r;
    ll t_add,ans,t_ch,sw;
}d[4000405];
ll n,m,a[1000105],q;
void build(int l,int r,int p){
    d[p].l=l; d[p].r=r;
    if (l==r){
        d[p].ans=a[l]; return;
    }
    int mid=(l+r)/2;
    build(l,mid,2*p); build(mid+1,r,2*p+1);
    d[p].ans=max(d[p*2+1].ans,d[p*2].ans);
}
void ch(int p,ll k){
    d[p].t_add+=k;
    d[p].ans+=k;
}
void ch2(int p,ll k){
    d[p].t_ch=k; d[p].sw=1; d[p].ans=k;
    d[p].t_add=0;
}
void push_down_ch(int p){
    if (d[p].sw==1){
        ch2(p*2,d[p].t_add),ch2(p*2+1,d[p].t_add);
        d[p].t_ch=0,d[p].sw=0;
    }
}
void push_down_add(int p){
    if (d[p].t_add!=0){
        push_down_ch(p);
        ch(p*2,d[p].t_add); ch(p*2+1,d[p].t_add);
        d[p].t_add=0;
    }
}
void push_down(int p){
    push_down_ch(p),push_down_add(p); 
}
void add(int l,int r,int p,ll k){
    if (d[p].l>=l&&d[p].r<=r){
        push_down_ch(p);
        ch(p,k); return;
    }
    if (d[p].l!=d[p].r) push_down(p);
    int mid=(d[p].l+d[p].r)/2;
    if (l<=mid) add(l,r,p*2,k);
    if (r>mid) add(l,r,p*2+1,k);
    d[p].ans=max(d[p*2].ans,d[p*2+1].ans);
}
void cov(int l,int r,int p,ll k){
    if (d[p].l>=l&&d[p].r<=r){
        ch2(p,k); return;
    }
    push_down(p);
    int mid=(d[p].l+d[p].r)/2;
    if (l<=mid) cov(l,r,p*2,k);
    if (r>mid) cov(l,r,p*2+1,k);
    d[p].ans=max(d[p*2].ans,d[p*2+1].ans);
}
ll gmax(int l,int r,int p){
    if (d[p].l>=l&&d[p].r<=r) return d[p].ans;
    push_down(p);
    int mid=(d[p].l+d[p].r)/2;
    ll ans=-1e16;
    if (l<=mid) ans=max(ans,gmax(l,r,p*2));
    if (r>mid) ans=max(ans,gmax(l,r,p*2+1));
    return ans;
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n>>q;
    for (int i=1;i<=n;i++){
        cin>>a[i];
    }
    build(1,n,1);
    ll op,l,r,x;
    for (int i=0;i<q;i++){
        cin>>op;
        switch(op){
            case 1:{
                cin>>l>>r>>x;
                cov(l,r,1,x);
                break;
            }
            case 2:{
                cin>>l>>r>>x;
                add(l,r,1,x);
                break;
            }
            case 3:{
                cin>>l>>r;
                cout<<gmax(l,r,1)<<"\n";
                break;
            }
        }
    }
    return 0;
}

|