AcWing 1264. 动态求连续区间和(线段树入门模板)
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int w[N];
struct Node{
int l, r, sum; //区间的左右端点和区间和
} tr[N * 4]; //开四倍大小
void pushup(int u) //更新区间和
{
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void build(int u, int l, int r) //建树
{
if(l == r) //左右区间端点相同,说明区间长度位1
{
tr[u] = {l, r, w[l]};
}
else //区间长度大于1
{
tr[u] = {l, r}; //先赋值所有端点
int mid = l + r >> 1; // 区间划分
build(u << 1, l, mid); //递归做子树
build(u << 1 | 1, mid + 1, r); //递归又子树
pushup(u);
}
}
int query(int u, int l, int r) //区间查询
{
if(tr[u].l >= l && tr[u].r <= r) //区间被覆盖
return tr[u].sum;
else
{
int mid = tr[u].l + tr[u].r >> 1;
int sum = 0;
if(l <= mid)
sum += query(u << 1, l, r);
if(r > mid)
sum += query(u << 1 | 1, l, r);
return sum;
}
}
void change(int u, int x, int v) //区间修改
{
if(tr[u].l == tr[u].r)
{
tr[u].sum += v;
}
else
{
int mid = tr[u].l + tr[u].r >> 1;
if(x <= mid)
change(u << 1, x, v);
else
change(u << 1 | 1, x, v);
pushup(u);
}
}
int main()
{
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; ++i)
cin >> w[i];
build(1, 1, n);
while(m--)
{
int k, a, b;
cin >> k >> a >> b;
if(k)
change(1, a, b);
else
cout << query(1, a, b) << endl;
}
return 0;
}