线段树区间修改模板不知道哪错了,求助大佬
  • 板块灌水区
  • 楼主不慕放糖
  • 当前回复12
  • 已保存回复12
  • 发布时间2021/12/23 21:34
  • 上次更新2023/10/28 13:48:58
查看原帖
线段树区间修改模板不知道哪错了,求助大佬
544113
不慕放糖楼主2021/12/23 21:34

P3372

#include<bits/stdc++.h>
using namespace std;
#define ls(p) p<<1//zdy
#define rs(p) p<<1|1
const int maxn=100000;
int a[1000000];
struct  tree{
    int data;
}t[maxn*4];
int add[100000];//lazy数组
void build(int p,int l,int r) {
    if(l==r){
        t[p].data=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(ls(p),l,mid),build(rs(p),mid+1,r);
    t[p].data=t[p*2].data+t[p*2+1].data;
}
void ad(int k,int l,int r,int v){//加标记的函数
    add[k]+=v;//打标记
    t[k].data+=(r-l+1)*v;
}
void pushdown(int k,int l,int r,int mid){//当前节点,左端点,右端点,中端点
    if(add[k]==0) return //没有标记;
    ad(ls(k),l,mid,add[k]);
    ad(rs(k),mid+1,r,add[k]);//下传
    add[k]=0;//下传后,原标记删除;
}
void modify(int k,int l,int r,int x,int y,int v){//当前节点,当前递归左端点,右端点,需要添加的区间,以及需要添加的值
        if(l>=x&&r<=y) return ad(k,l,r,v);//递归到目标区间的子区间,不在向下递归,直接标记
        int mid=(l+r)>>1;
        pushdown(k,l,r,mid);
        if(x<=mid) modify(k*2,l,mid,x,y,v);//递归左子树
        if(mid<y) modify(k*2+1,mid+1,r,x,y,v);//递归右子树
        t[k].data=t[ls(k)].data+t[rs(k)].data;
        
}
int query(int k,int l,int r,int x,int y){//基本上与modify函数语句一样,只不过需要·1
    if(l>=x&&r<=y) return add[k];
    int mid=(l+r)>>1,res=0;
    pushdown(k,l,r,mid);//标记下传
    if(x<=mid) res+=query(k*2,l,mid,x,y);//递归左子树
    if(mid<y) res+=query(k*2+1,mid+1,r,x,y);//递归右子树
    return res;
} 
int  main(){
    int n,m;
    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;
            modify(1,1,n,x,y,k);
        }
        if(op==2){
            int x,y;
            cin>>x>>y;
            cout<<query(1,1,n,x,y)<<endl;
        }
    }
    return 0;

}
2021/12/23 21:34
加载中...