线段树(5)成断更新 poj3468

来源:互联网 发布:手机扫描端口 编辑:程序博客网 时间:2024/04/28 22:49

题目链接:http://poj.org/problem?id=3468

WA很长时间,首先pushdown函数写的有很大问题。add在更新到子节点要考虑子节点是否是统一加上某个值。所以要加if判断。。。具体见代码后来看到http://www.notonlysuccess.com/index.php/segment-tree-complete/里的代码,大牛用很巧妙的方法避开了判断还节省了空间。佩服、

code:

#include <stdio.h>#include <string.h>const int MAX = 100000 + 10;int n, q;char order[2];struct node{int l;int r;__int64 sum;__int64 add;bool flag;}a[MAX<<2];void pushup(int pos){a[pos].sum = a[pos<<1].sum + a[pos<<1|1].sum;}void pushdown(int pos){a[pos].flag = false;if (a[pos<<1].flag){a[pos<<1].add += a[pos].add;}else{a[pos<<1].add = a[pos].add;}if (a[pos<<1|1].flag){a[pos<<1|1].add += a[pos].add;}else{a[pos<<1|1].add = a[pos].add;}a[pos<<1].flag = true;a[pos<<1|1].flag = true;a[pos<<1].sum += (a[pos<<1].r - a[pos<<1].l + 1) * a[pos].add;a[pos<<1|1].sum += (a[pos<<1|1].r - a[pos<<1|1].l + 1) * a[pos].add;}void build(int l, int r, int pos){a[pos].l = l ;a[pos].r = r;a[pos].add = 0;a[pos].flag =false;if (l == r){scanf("%I64d", &a[pos].sum);return;}int mid = (l + r) >> 1;build(l, mid, pos<<1);build(mid+1, r, pos<<1|1);pushup(pos);}void update(int l, int r, __int64 add, int pos){if (a[pos].r == r&& a[pos].l == l){if (a[pos].flag){a[pos].add += add;}else{a[pos].add = add;}a[pos].flag = true;a[pos].sum +=  (r - l + 1) * add;return;}if (a[pos].flag){pushdown(pos);}int mid = (a[pos].l + a[pos].r) >> 1;if (r<=mid){update(l, r, add, pos<<1);}else if (l > mid){update(l, r, add, pos<<1|1);}else{update(l, mid, add, pos<<1);update(mid+1, r, add, pos<<1|1);}pushup(pos);}__int64 query(int l, int r, int pos){if (a[pos].l == l && a[pos].r == r){return a[pos].sum;}if (a[pos].flag){pushdown(pos);}int mid = (a[pos].l + a[pos].r) >> 1;if (r<=mid){return query(l, r, pos<<1);}else if (l > mid){return query(l, r, pos<<1|1);}else{return query(l, mid, pos<<1) + query(mid+1, r, pos<<1|1);}}int main(){int x, y;__int64 z;while (scanf("%d%d", &n, &q) == 2){build(1, n, 1);while (q--){scanf("%s", order);if (order[0] == 'Q'){scanf("%d%d", &x, &y);printf("%I64d\n", query(x, y, 1));}else{scanf("%d%d%I64d", &x, &y, &z);update(x, y, z, 1);}}}return 0;}/*10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4*/


 

原创粉丝点击