RT。刚学不到几小时,不知道哪里写错了……
#include <bits/stdc++.h>
using namespace std;
#define MAXN 500001
int n, m, x, y, opt;
long long k;
long long a[MAXN];
struct Tree{ // 线段树结点
int l, r;
long long sum;
}tree[MAXN<<2]; // 注意要开到4倍空间
void build(int l, int r, int p){ // 建线段树
tree[p].l = l; // 定义左边界
tree[p].r = r; // 定义右边界
if (l == r){ // 如果[l,r]为一个单点
tree[p].sum = a[l]; // 则它的权值为那个单点的数
return;
}
int mid = (l+r)>>1;
build(l, mid, p<<1); // 递归查找左右儿子
build(mid+1, r, (p<<1)+1);
tree[p].sum = tree[p<<1].sum + tree[(p<<1)+1].sum; // 即为左右儿子的权值之和
}
void add(int l, int r, long long k, int p){ // [l,r]加上k,现在搜到了p
if (tree[p].l >= l && tree[p].r <= r){ // 完全在区间内
tree[p].sum += k;
return;
}
if (tree[p<<1].r >= l) add(l, r, k, p<<1); // 递归左儿子
if (tree[(p<<1)+1].l <= r) add(l, r, k, (p<<1)+1); // 递归右儿子
}
long long query(int i, int p){ // 查询单点i的值
long long ans = tree[p].sum;
if (tree[p].l == tree[p].r) return ans; // 单点
if (i <= tree[p<<1].r) ans += query(i, p<<1); // 递归左儿子
if (i >= tree[(p<<1)+1].l) ans += query(i, (p<<1)+1); // 递归右儿子
return ans; // 返回
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i=1; i<=n; i++) cin >> a[i];
build(1, n, 1);
while (m--){
cin >> opt;
if (opt == 1){ // 区间修改
cin >> x >> y >> k;
add(x, y, k, 1);
}else{ // 单点查询
cin >> x;
cout << query(x, 1) << '\n';
}
}
return 0;
}