#include <stdio.h>
int sum[100];
void Build(int lift, int right, int rt);
void Updata(int point, int add, int lift, int right, int rt);
int query(int L, int R, int l, int r, int rt);
int main()
{
Build(1, 8, 1);
Updata(1, 2, 1, 8, 1);
printf("%d\n", query(1, 3, 1, 8, 1));
for (int i = 1; i <= 15; i++)
printf("%d\n", sum[i]);
return 0;
}
// 构建一个线段树
void Build(int lift, int right, int rt)
{
// l 代表构建的左端; r 代表构建的右端; rt 代表当前的结点
// 一个基准
if (right == lift) {
scanf("%d", &sum[rt]);
return ;
}
int m = (lift + right) / 2;
// 构建左儿子
Build(lift, m, rt*2);
// 构建右儿子
Build(m+1, right, rt*2+1);
// 构建好左儿子与右儿子之后, 求出双亲
sum[rt] = sum[rt*2] + sum[rt*2+1];
}
// 更新单点 去加上一个数
void Updata(int point, int add, int lift, int right, int rt)
{
// point 代表要更新的点; add 代表要加的数;
// l 代表构建的左端; r 代表构建的右端; rt 代表当前的结点
// 一个基准
if (lift == right) {
sum[rt] += add;
return ;
}
int m = (lift + right) / 2;
// 开始寻找是区间 : 在左儿子还是 右儿子
if (point <= m) // 即在左儿子
Updata(point, add, lift, m, rt*2);
else
Updata(point, add, m+1, right, rt*2+1);
// 还要更新上面的
sum[rt] = sum[rt*2] + sum[rt*2+1];
}
// 区间求和
int query(int L, int R, int l, int r, int rt)
{
// L 为要求的区间左端; R 为要求的区间右端;
// l 为当前函数区间的左端; R 当前函数区间的右端
int Sum = 0;
// 一个基准: 找到L R 所对应的区间后返回;
if (l >= L && r <= R)
return (Sum += sum[rt]);
int m = (l + r) / 2;
if (L <= m)
Sum += query(L, R, l, m, rt*2);
if (R > m)
Sum += query(L, R, m+1, r, rt*2+1);
return Sum;
}
int sum[100];
void Build(int lift, int right, int rt);
void Updata(int point, int add, int lift, int right, int rt);
int query(int L, int R, int l, int r, int rt);
int main()
{
Build(1, 8, 1);
Updata(1, 2, 1, 8, 1);
printf("%d\n", query(1, 3, 1, 8, 1));
for (int i = 1; i <= 15; i++)
printf("%d\n", sum[i]);
return 0;
}
// 构建一个线段树
void Build(int lift, int right, int rt)
{
// l 代表构建的左端; r 代表构建的右端; rt 代表当前的结点
// 一个基准
if (right == lift) {
scanf("%d", &sum[rt]);
return ;
}
int m = (lift + right) / 2;
// 构建左儿子
Build(lift, m, rt*2);
// 构建右儿子
Build(m+1, right, rt*2+1);
// 构建好左儿子与右儿子之后, 求出双亲
sum[rt] = sum[rt*2] + sum[rt*2+1];
}
// 更新单点 去加上一个数
void Updata(int point, int add, int lift, int right, int rt)
{
// point 代表要更新的点; add 代表要加的数;
// l 代表构建的左端; r 代表构建的右端; rt 代表当前的结点
// 一个基准
if (lift == right) {
sum[rt] += add;
return ;
}
int m = (lift + right) / 2;
// 开始寻找是区间 : 在左儿子还是 右儿子
if (point <= m) // 即在左儿子
Updata(point, add, lift, m, rt*2);
else
Updata(point, add, m+1, right, rt*2+1);
// 还要更新上面的
sum[rt] = sum[rt*2] + sum[rt*2+1];
}
// 区间求和
int query(int L, int R, int l, int r, int rt)
{
// L 为要求的区间左端; R 为要求的区间右端;
// l 为当前函数区间的左端; R 当前函数区间的右端
int Sum = 0;
// 一个基准: 找到L R 所对应的区间后返回;
if (l >= L && r <= R)
return (Sum += sum[rt]);
int m = (l + r) / 2;
if (L <= m)
Sum += query(L, R, l, m, rt*2);
if (R > m)
Sum += query(L, R, m+1, r, rt*2+1);
return Sum;
}