您的位置:首页 > 其它

[POJ 2368 A Simple Problem with Integers] 树状数组区间修改、区间查询

2017-01-02 23:35 459 查看

[POJ 2368 A Simple Problem with Integers] 树状数组区间修改、区间查询

知识点:
data structure
binary index tree


1. 题目链接

[POJ 2368 A Simple Problem with Integers]

2. 题意描述

对数组an进行q次区间修改(加上一个数),区间查询。

1≤n,q≤105,−109≤Ai≤109。

3. 解题思路

这个用线段树做也就是一个无脑题。之前这类区间查询的还真的很少用树状数组做。

原理:原数组为ai,差分数组为di=ai−ai−1;则an=∑ni=1di;

所以,∑i=1nai=∑i=1n∑j=1idj=∑i=1n[(n−i+1)∗di]=(x+1)∑i=1ndi−∑i=1n(di∗i)

通过维护差分数组di,以及di∗i。就可以维护原数组的前缀和。进而维护出原数组的区间和。

4. 实现代码

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int MAXN = 100000 + 5;

int n, q;

template<class T>
struct BIT {
T C[MAXN];
void I() { memset(C, 0, sizeof(C)); }
inline T lowbit(T x) { return x & (-x); }
void update(int x, LL val) {
while(x < MAXN) { C[x] += val; x += lowbit(x); }
}
T query(int x) {
T ret = 0;
while(x > 0) { ret += C[x]; x -= lowbit(x); }
return ret;
}
};
BIT<LL> a, b;
void update(int x, LL v) { a.update(x, v); b.update(x, v * x); }
void update(int l, int r, LL v) { update(l, v); update(r + 1, -v); }
LL presum(int x) { return (LL)(x + 1) * a.query(x) - b.query(x); }
LL query(int l, int r) { return presum(r) - presum(l - 1); }

int main() {
#ifdef ___LOCAL_WONZY___
freopen("input.txt", "r", stdin);
#endif // ___LOCAL_WONZY___
char op[5];
LL l, r, v;
while(~scanf("%d %d", &n, &q)) {
a.I(); b.I();
vector<LL> A(n + 1);
A[0] = 0;
for(int i = 1; i <= n; i++) {
scanf("%lld", &A[i]);
update(i, A[i] - A[i - 1]); /// 注意这里
}
while(q --) {
scanf("%s %lld %lld", op, &l, &r);
if(op[0] == 'Q') {
printf("%lld\n", query(l, r));
} else {
scanf("%lld", &v);
update(l, r, v);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐