POJ - 3468 A Simple Problem with Integers(线段树成段更新,查询区间和)

来源:互联网 发布:炼数成金 大数据分析师 编辑:程序博客网 时间:2024/06/15 09:06
A Simple Problem with Integers
Time Limit: 5000MS Memory Limit: 131072KB 64bit IO Format: %I64d & %I64u

Submit Status

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 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4

Sample Output

455915

 

线段树,成段更新,感觉还是不理解,这题还需要注意下数据范围。

#include <iostream>#include <cstdio>#include<cstring>using namespace std;#define LL long long#define max(a,b) a>b?a:bconst 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);}}}
0 0
原创粉丝点击