POJ - 3468 - A Simple Problem with Integers 【线段树 区间修改】
http://poj.org/problem?id=3468
要求:
1. 区间修改,增大、减小一个固定值
2. 查询区间和
#include <cstdio> #include <iostream> #define lson rt<<1, l, m #define rson rt<<1|1, m+1, r using namespace std; typedef long long LL; const int MAXN = 131072 + 5; int n; LL add[MAXN << 1]; LL sum[MAXN << 1]; void pushup(int rt) { sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; } void pushdown(int rt, int m) { if(add[rt]) { add[rt << 1] += add[rt]; add[rt << 1 | 1] += add[rt]; sum[rt << 1] += (m - (m >> 1)) * add[rt]; sum[rt << 1 | 1] += (m >> 1) * add[rt]; add[rt] = 0; } } void build(int rt, int l, int r) { add[rt] = 0; if(l == r) { scanf("%lld", &sum[rt]); } else { int m = (l + r) >> 1; build(lson); build(rson); pushup(rt); } } void update(int ql, int qr, int x, int rt, int l, int r) { if(ql <= l && r <= qr) { // 传递到最上层就终止,lazy思想 add[rt] += x; sum[rt] += (r - l + 1) * x; } else { pushdown(rt, r - l + 1); // 马上要更新子节点了,必须要把add信息传递下去 int m = (l + r) >> 1; if(ql <= m) update(ql, qr, x, lson); if(qr > m) update(ql, qr, x, rson); pushup(rt); } } LL query(int ql, int qr, int rt, int l, int r) { if(ql <= l && r <= qr) { return sum[rt]; } // 因为查询的区间涉及到没有获取add信息的底层区间,所以没有办法,必须要将add信息传达下去 pushdown(rt, r - l + 1); int m = (l + r) >> 1; LL ret = 0; if(ql <= m) ret += query(ql, qr, lson); if(qr > m) ret += query(ql, qr, rson); return ret; } int main () { int q; scanf("%d%d", &n, &q); build(1, 1, n); char s[2]; int a, b, c; while(q--) { scanf("%s", s); if(s[0] == 'Q') { scanf("%d%d", &a, &b); printf("%lld\n", query(a, b, 1, 1, n)); } else { scanf("%d%d%d", &a, &b, &c); update(a, b, c, 1, 1, n); } } return 0; }