线段树 从入门到进阶(超清晰,简单易懂)_进阶线段树-CSDN博客
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int a[N];
int ans;
struct segment_tree {
struct node {
int l, r, num;
} tr[N * 4];
void build(int p, int l, int r) {
tr[p] = {l, r, 0};
if (l == r) {
tr[p].num = a[l];
return;
}
int mid = l + r >> 1;
build(p << 1, l, mid); //实际上就是p*2 左子树
build(p << 1 | 1, mid + 1, r); //实际上就是p*2+1 右子树
}
void modify(int p, int l, int r, int k) {
//如果当前区间被目标区间覆盖了就直接输出其区间和
if (tr[p].l >= l && tr[p].r <= r) {
tr[p].num += k;
return;
}
int mid = tr[p].l + tr[p].r >> 1;
if (l <= mid)
modify(p << 1, l, r, k); //如果当前区间和目标区间的左孩子区间有交集,就搜索左区间
if (r > mid)
modify(p << 1 | 1, l, r, k);
}
void query(int p, int x) {
ans += tr[p].num;
if (tr[p].l == tr[p].r)
return;
int mid = tr[p].l + tr[p].r >> 1;
if (x <= mid)
query(p << 1, x);
else
query(p << 1 | 1, x);
}
} st;
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
//建树
st.build(1, 1, n);
for (int i = 1; i <= m; i++) {
int c;
cin >> c;
if (c == 1) {
int x, y, k;
cin >> x >> y >> k;
st.modify(1, x, y, k);
} else {
ans = 0;
int x;
cin >> x;
st.query(1, x);
printf("%d\n", ans);
}
}
return 0;
}