照着某站学的线段树, 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;
}