Time Limit: 5000MS | Memory Limit: 131072KB | 64bit IO Format: %I64d & %I64u |
Description
给出了一个序列,你需要处理如下两种询问。
"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。
"Q a b" 询问[a, b]区间中所有值的和。
Input
第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.
第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。
接下来Q行询问,格式如题目描述。
Output
对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。
Sample Input
10 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4
Sample Output
4 55 9 15
线段树,成段更新,感觉还是不理解,这题还需要注意下数据范围。
#include <iostream> #include <cstdio> #include<cstring> using namespace std; #define LL long long #define max(a,b) a>b?a:b const LL MAXN = 200000 + 1000; LL num[MAXN]; LL father[MAXN]; LL anssum; struct node { LL l, r; LL Sum; LL lazy; }tree[MAXN * 3]; inline void pushUp(LL i) { LL ls = i << 1, rs = ls + 1; tree[i].Sum = tree[ls].Sum + tree[rs].Sum; } void pushDown(LL i) { LL ls = i << 1, rs = ls + 1; tree[ls].lazy += tree[i].lazy; tree[rs].lazy += tree[i].lazy; tree[ls].Sum += tree[i].lazy*(tree[ls].r - tree[ls].l + 1); tree[rs].Sum += tree[i].lazy*(tree[rs].r - tree[rs].l + 1); tree[i].lazy = 0; } void build(LL l, LL r, LL i) { tree[i].lazy = 0; tree[i].l = l; tree[i].r = r; if (l == r) { tree[i].Sum = num[l]; father[l] = i; return; } LL ls = i << 1, rs = ls + 1; LL m = (l + r) >> 1; build(l, m, ls); build(m + 1, r, rs); pushUp(i); } void update(LL l, LL r, LL i, LL v) { if (l <= tree[i].l && r >= tree[i].r) { tree[i].lazy += v; tree[i].Sum += v*(tree[i].r - tree[i].l + 1); return; } if (tree[i].lazy) pushDown(i); LL m = (tree[i].l + tree[i].r) >> 1, ls = i << 1, rs = ls + 1; if(l<=m) update(l, r, ls, v); if(r>m) update(l, r, rs, v); pushUp(i); } void query(LL l, LL r, LL i) { if (l <= tree[i].l && r >= tree[i].r) { anssum += tree[i].Sum; return; } if (tree[i].lazy) pushDown(i); LL m = (tree[i].l + tree[i].r) >> 1, ls = i << 1, rs = ls + 1; if (l <= m) query(l, r, ls); if (r > m) query(l, r, rs); } int main() { LL n, q; scanf("%I64d %I64d", &n, &q); for (LL i = 1; i <= n; i++) scanf("%I64d", &num[i]); build(1, n, 1); char op; LL a, b, c; while (q--) { cin >> op; if (op == 'C') { scanf("%I64d %I64d %I64d", &a, &b, &c); update(a, b, 1, c); } else { scanf("%I64d %I64d", &a, &b); anssum = 0; query(a, b, 1); printf("%I64d\n", anssum); } } }