1. 点查询,区间更新
基础版本
2. 区间更新,点查询
使用差分,维护差分数组d[i] = a[i] - a[i - 1]
。
区间更新变成了[l, r]
两端l
和r
的更新,点查询也就变成了[1, x]
的区间更新。
3. 区间更新,区间查询
使用差分,维护差分数组d1[i] = a[i] - a[i - 1]
和 d2[i] = i * (d2[i] - d2[i - 1])
。
区间更新的方式和2
相同,区间查询是(r + 1) * query(d1, r) - query(d2, r)
。通过差分推一推就能得到。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
ll a[maxn], b[maxn];
ll lowbit(ll t) { // core
return t & (-t);
}
ll n,q;
void update(ll a[], ll x, ll v) {
for (ll i = x; i <= n; i += lowbit(i)) {
a[i] += v;
}
}
ll query(ll a[], ll x) {
ll res = 0;
for (ll i = x; i >= 1; i -= lowbit(i)) {
res += a[i];
}
return res;
}
ll query_inner(ll x) {
return (x + 1) * query(a, x) - query(b, x);
}
ll range_query(ll l, ll r) {
return query_inner(r) - query_inner(l - 1);
}
int main() {
scanf("%d%d", &n, &q);
ll pre = 0;
for (int i = 1; i <= n; ++i) {
ll tmp;
scanf("%lld", &tmp);
ll d = tmp - pre;
update(a, i, d);
update(b, i, d * i);
pre = tmp;
}
for (int i = 0; i < q; ++i) {
int op;
scanf("%d", &op);
if (op == 1) {
ll l, r;
ll x;
scanf("%lld%lld%lld", &l, &r, &x);
update(a, l, x);
update(a, r + 1, -x);
update(b, l, x * l);
update(b, r + 1, -x * (r + 1));
}
else {
ll l, r;
scanf("%lld%lld", &l, &r);
printf("%lld\n", range_query(l, r));
}
}
return 0;
}
4. 二维数状数组
class NumMatrix {
public:
vector<vector<int>> A;
int n;
int m;
NumMatrix(vector<vector<int>> matrix) {
n = matrix.size();
m = matrix[0].size();
A = vector<vector<int>>(n + 1, vector<int> (m + 1, 0));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
update(i + 1, j + 1, matrix[i][j]);
}
}
}
void update(int row, int col, int val) {
for (int i = row; i <= n; i += i&-i) {
for (int j = col; j <= m; j += j&-j) {
A[i][j] += val;
}
}
}
int query(int row, int col) {
int result = 0;
for (int i = row; i >= 1; i -= i&-i) {
for (int j = col; j >= 1; j -= j&-j) {
result += A[i][j];
}
}
return result;
}
int sumRegion(int row1, int col1, int row2, int col2) {
row1 += 1, col1 += 1, row2 += 1, col2 += 1;
return query(row2, col2) + query(row1 - 1, col1 - 1) - query(row1 - 1, col2) - query(row2, col1 - 1);
}
};
%%%%%%
加油!