LOJ132. 树状数组 3 :区间修改,区间查询 题解
Posted 劝君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LOJ132. 树状数组 3 :区间修改,区间查询 题解相关的知识,希望对你有一定的参考价值。
题目链接:https://loj.ac/p/132
解题思路:
设元素组元素为 \\(a_i\\),其方差数组为 \\(d_i = a_i - a_{i-1}\\)
则 \\(a_x = \\sum\\limits_{i=1}^{x} d_i\\)
所以有 \\(\\sum\\limits_{i=1}^{x} a_i = \\sum\\limits_{i=1}^{x} \\sum\\limits_{j=1}^{i} d_j = \\sum\\limits_{i=1}^x (x-i+1) \\times d_i\\)
于是有 \\(\\sum\\limits_{i=1}^x = (x+1) \\sum\\limits_{i=1}^x d_i - \\sum\\limits_{i=1}^x d_i \\times i\\)
于是将原数组差分后维护两个树状数组,一个维护 \\(d_i\\),一个维护 \\(d_i \\times i\\)。即可解决这个问题。
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000010;
int n, q, op, l, r;
long long x, a[maxn];
struct BIT {
long long c[maxn];
int lowbit(int x) {
return x & -x;
}
void add(int p, long long x) {
while (p <= n) {
c[p] += x;
p += lowbit(p);
}
}
long long query(int p) {
long long res = 0;
while (p) {
res += c[p];
p -= lowbit(p);
}
return res;
}
} t1, t2;
int main()
{
cin >> n >> q;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
t1.add(i, a[i]-a[i-1]);
t2.add(i, (a[i]-a[i-1])*i);
}
while (q --) {
cin >> op >> l >> r;
if (op == 1) {
cin >> x;
t1.add(l, x);
t1.add(r+1, -x);
t2.add(l, x*l);
t2.add(r+1, -x*(r+1));
}
else {
long long rval = (r+1) * t1.query(r) - t2.query(r);
long long lval = l* t1.query(l-1) - t2.query(l-1);
cout << rval - lval << endl;
}
}
return 0;
}
以上是关于LOJ132. 树状数组 3 :区间修改,区间查询 题解的主要内容,如果未能解决你的问题,请参考以下文章