线段树求区间和
int arr[MAX];//arr[0]不用
int ans;
struct node{
int l,r;//左右端点
int value;//线段值
int add;//延迟标记
}tree[4*MAX];//tree[0]不用
void build(int v,int l,int r){//节点v,区间【l,r】
tree[v].l=l;
tree[v].r=r;
if(l==r)
tree[v].value=arr[l];
else{
int mid=(l+r)/2;
build(v*2,l,mid);
build(v*2+1,mid+1,r);
tree[v].value=tree[v*2].value+tree[v*2+1].value;
}
}
void update(int v,int l,int r,int m){//更新区间【l,r】,加上m(未更新父节点)
if(tree[v].l==l&&tree[v].r==r){
tree[v].value+=m*(r-l+1);
tree[v].add=m;
return;
}
if(tree[v].add){
tree[v*2].add+=tree[v].add;
tree[v*2+1].add+=tree[v].add;
tree[v].add=0;
}
int mid=(tree[v].l+tree[v].r)/2;
if(r<=mid)
update(v*2,l,r,m);
else if(l>mid)
update(v*2+1,l,r,m);
else{
update(v*2,l,mid,m);
update(v*2+1,mid+1,r,m);
}
}
void query(int v,int l,int r){//查询【l,r】的和
if(tree[v].l==l&&tree[v].r==r){
ans+=tree[v].value;
return;
}
if(tree[v].add){
tree[v*2].add+=tree[v].add;
tree[v*2+1].add+=tree[v].add;
tree[v].add=0;
}
int mid=(tree[v].l+tree[v].r)/2;
if(r<=mid)
query(v*2,l,r);
else if(l>mid)
query(v*2+1,l,r);
else{
query(v*2,l,mid);
query(v*2+1,mid+1,r);
}
}