线段树模板
#include<bits/stdc++.h>
using namespace std;
int segTree[100];
int add[100]; // 懒惰数组
//每次修改时, 可以不修改到下面区间具体的值, 先由懒惰数组记录 等查询到具体区间时再加上
void build(int l, int r, int root){
// l r 表示区间范围
if(l == r){
cin >> segTree[root];
return ;
}
int mid = (l+r)>>1;
build(l, mid, root<<1);
build(mid+1, r, root<<1|1);
segTree[root] = segTree[root<<1] + segTree[root<<1|1];
}
void PushDown(int ln, int rn, int root){
// 使用懒惰数组更新区间
// ln 左子区间的数量
// rn 右子区间的数量
// root 数组下标
if(add[root]){
//将懒惰数组的值传给子区间懒惰数组
add[root<<1] += add[root];
add[root<<1|1] += add[root];
//再由子区间的懒惰数组更新子区间的值
segTree[root<<1] += ln * add[root];
segTree[root<<1|1] += rn * add[root];
add[root] = 0;
}
}
int Query(int L, int R, int l, int r, int root){
// L R 表示查询的范围
// l r 表示要查询的区间
// root 表示数组的下标
if(l <= L &&r >= R){
// 查询的范围在要查询的区间内,直接返回值
return segTree[root];
}
int mid = (L + R) >> 1;
int ans = 0;
// 使用懒惰数组更新具体的区间的值
PushDown(mid-l+1, r-mid, root);
if(l <= mid) ans += Query(L, mid, l, r, root<<1);//查询的区间在查询的范围左部也有区间
if(r > mid) ans += Query(mid+1, R, l, r, root<<1|1);//查询的区间在查询的范围右部也有区间
return ans;
}
void update(int L, int R, int l, int r, int value, int root){
// L R 表示修改的范围
// l r 将区间l-r的值都加上value
// value 修改的值
/*
不使用懒惰数组
if(L == R){
segTree[root] += value;
return ;
}
*/
//使用懒惰数组
if(l <= L && R <= r){
segTree[root] += (R-L+1)*value;
add[root] += value;
return ;
}
int mid = (L + R) >> 1;
if(l <= mid) update(L, mid, l, r, value, root<<1);//修改的区间在查询的范围左部也有区间
if(r > mid) update(mid+1, R, l, r, value, root<<1|1);//修改的区间在查询的范围右部也有区间
// 更新区间值
segTree[root] = segTree[root<<1] + segTree[root<<1|1];
}
int main(){
int n;
cin >> n;
// 7
build(1, n, 1);
// 1 2 3 4 5 6 7
cout << segTree[13] << endl;
cout << Query(1, n, 2, 4, 1) << endl; // 在区间1-n中查询区间2-4的和值
update(1,n, 1, 3, 5, 1);
cout << segTree[8] << " " << segTree[9] << " " << segTree[10] << endl;
cout << Query(1, n, 2, 2, 1) << endl; // 在区间1-n中查询区间2-4的和值
cout << segTree[8] << " " << segTree[9] << " " << segTree[10] << endl;
}