一个简单的整数问题
题目
给定长度为N的数列A,然后输入M行操作指令。
第一类指令形如“C l r d”,表示把数列中第l~r个数都加d。
第二类指令形如“Q X”,表示询问数列中第x个数的值。
对于每个询问,输出一个整数表示答案。
输入格式
第一行包含两个整数N和M。
第二行包含N个整数A[i]。
接下来M行表示M条指令,每条指令的格式如题目描述所示。
输出格式
对于每个询问,输出一个整数表示答案。
每个答案占一行。
数据范围
输入样例
10 5
1 2 3 4 5 6 7 8 9 10
Q 4
Q 1
Q 2
C 1 6 3
Q 2
输出样例
4
1
2
5
题解
思路
-
普通树状数组只支持单点修改和查询前缀和(因此也可以求区间和)
-
所以我们考虑用树状数组维护差分序列
-
那么区间修改就相当于单点修改,求某个数相当于求差分数组前缀和
#include <iostream>
using namespace std;
const int N = 1e5 + 20;
int n, m, a[N], tr[N];
inline int lowbit(int x) {
return x & -x;
}
void add(int x, int t) {
for (; x <= n; x += lowbit(x)) tr[x] += t;
}
int sum(int x) {
int res = 0;
for (; x; x -= lowbit(x)) res += tr[x];
return res;
}
int main () {
cin >> n >> m;
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1; i <= n; i ++) add(i, a[i] - a[i-1]);
char ch;
int l, r, c;
while (m --) {
cin >> ch;
if (ch == 'Q') {
cin >> c;
cout << sum(c) << endl;
}
else {
cin >> l >> r >> c;
add(l, c), add(r + 1, -c);
}
}
return 0;
}