线段树模板-1 求改
  • 板块学术版
  • 楼主SamHJD
  • 当前回复4
  • 已保存回复4
  • 发布时间2022/8/30 11:32
  • 上次更新2023/10/27 13:06:45
查看原帖
线段树模板-1 求改
565684
SamHJD楼主2022/8/30 11:32

照着某站学的线段树, update函数只修改一个数的值, 求怎么改成修改区间的值.

#include<bits/stdc++.h>
using namespace std;
int n,m,arr[10000001],tree[10000001];

//这是快读快写
inline int read(){int s=0,w=1;char ch=getchar();while(ch<'0' || ch>'9'){if(ch=='-')w=-1;ch=getchar();}while(ch>='0' && ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;}
inline void write(int x){if(x<0){putchar('-');x=-x;}if(x>9) write(x/10);putchar(x%10+'0');}

//建树
void build(int node,int start,int end){
    if(start==end) tree[node]=arr[start];
    else{
        int mid=(start+end)/2;
        int left_node=2*node+1;
        int right_node=2*node+2;
        build(left_node,start,mid);
        build(right_node,mid+1,end);
        tree[node]=tree[left_node]+tree[right_node];
    }
}


//求改------------
void update(int node,int start,int end,int idx,int val){//idx是下标,val是修改的值(不是增加的值)
    if(start==end) arr[idx]=val,tree[node]=val;//到头了, 直接修改
    else{
        int mid=(start+end)/2;//中点
        int left_node=2*node+1;//左孩子节点
        int right_node=2*node+2;//右孩子节点
        if(idx>=start && idx<=mid){//在左树内
            update(left_node,start,mid,idx,val);//左树
        }
        else{//在右树内
            update(right_node,mid+1,end,idx,val);//右树
        }
        tree[node]=tree[left_node]+tree[right_node];//合并,node为当前节点
    }
}
//求改------------


int query(int node,int start,int end,int L,int R){
    if(R<start || L>end) return 0;
    else if(L<=start && R>=end) return tree[node];
    if(start==end) return tree[node];
    else{
        int mid=(start+end)/2;
        int left_node=2*node+1;
        int right_node=2*node+2;
        int sum_left=query(left_node,start,mid,L,R);
        int sum_right=query(right_node,mid+1,end,L,R);
        return sum_left+sum_right;
    }
}
int main(){
	//tree数组下标从0开始
    n=read();m=read();
    for(int i=0;i<n;i++){
        arr[i]=read();
    }
    build(0,0,n-1);
    for(int i=1;i<=m;i++){
        int q=read(),x=read(),y=read(),k;
        if(q==1){
            k=read();
            for(int j=x;j<=y;j++) update(0,0,n-1,j-1,arr[j-1]+k);//只能打暴力修改, 最后三个点TLE
        }
        if(q==2){
            write(query(0,0,n-1,x-1,y-1));
            puts("");
        }
    }
    return 0;
}
2022/8/30 11:32
加载中...