线段树求调

P3372 【模板】线段树 1

hzc0829 @ 2024-09-15 10:16:51

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[100010];
struct note{
    int l,r;
    long long sum,add=0;
}tr[400010];
void push_up(int p){
    tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum;
}
void push_down(int p){
    tr[p<<1].add+=tr[p].add;
    tr[p<<1|1].add+=tr[p].add;
    tr[p<<1].sum+=(tr[p<<1].r-tr[p<<1].l+1)*tr[p].add;
    tr[p<<1|1].sum+=(tr[p<<1|1].r-tr[p<<1|1].l+1)*tr[p].add;
    tr[p].add=0;
}
void build(int rt,int l,int r){
    tr[rt].l=l;
    tr[rt].r=r;
    if(l==r){
        tr[rt].sum=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(rt<<1,l,mid);
    build(rt<<1|1,mid+1,r);
    push_up(rt);
}
void modify(int rt,int l,int r,int lpos,int rpos,int ad){
    if(l>=lpos&&r<=rpos){
        tr[rt].sum+=(tr[rt].r-tr[rt].l+1)*ad; 
        tr[rt].add+=ad;
        return;
    }
    push_down(rt);
    int mid=(l+r)/2;
    if(lpos<=mid){
        modify(rt<<1,l,mid,lpos,rpos,ad);
    }else if(rpos>mid){
        modify(rt<<1|1,mid+1,r,lpos,rpos,ad);
    }
    push_up(rt);
}
long long query(int rt,int l,int r,int lpos,int rpos){
    if(l>=lpos&&r<=rpos){
        return tr[rt].sum;
    }
    push_down(rt);
    int mid=(l+r)/2;
    long long res=0;
    if(lpos<=mid){
        res+=query(rt<<1,l,mid,lpos,rpos);
    }else if(rpos>mid){
        res+=query(rt<<1|1,mid+1,r,lpos,rpos);
    }
    return res;
}
void SolveOp1(int x,int y,int k){
    modify(1,1,n,x,y,k);
}
long long SolveOp2(int x,int y){
    return query(1,1,n,x,y);
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    build(1,1,n);
    while(m--){
        int op;
        cin>>op;
        if(op==1){
            int x,y,k;
            cin>>x>>y>>k;
            SolveOp1(x,y,k);
        }else{
            int x,y;
            cin>>x>>y;
            cout<<SolveOp2(x,y)<<endl;
        }
    }
    return 0;
}

by dayz_break404 @ 2024-09-15 10:35:48

这是区间修改,modify 函数和 query 函数里的 else if 改成 if 即可。


by hzc0829 @ 2024-09-15 11:25:23

谢谢


|