线段树(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*/
- 线段树(5)成断更新 poj3468
- 线段树(成段更新 关于延迟标记) poj3468
- POJ3468(线段树区间更新)
- POJ3468(线段树之区间更新)
- POJ3468(线段树+延迟更新)
- 线段树区间更新poj3468
- poj3468线段树区间更新
- POJ3468线段树区间更新
- POJ3468 线段树 区间更新
- poj3468(线段树成段更新)
- poj3468(线段树)
- poj3468(线段树)
- 线段树POJ3468(成段更新,区间求和)
- 线段树POJ3468(成段更新,区间求和)
- POJ3468-A Simple Problem with Integers(线段树 成段更新求和)
- poj3468 线段树+延迟更新
- poj3468 线段树区间更新,区间求和
- poj3468 线段树成段更新
- AVD存放路径更改
- C++内存管理详解
- Suse下amarok不能播放mp3解决
- OpenGL ES之GLSurfaceView学习二:非交互式的实例
- J2EE规范
- 线段树(5)成断更新 poj3468
- 关键帧动画CAKeyframeAnimation
- I NEED A OFFER!
- android 开发布局之TableLayout
- linux启动顺序
- java视频上传截图
- OpenGL ES之GLSurfaceView学习三:交互式的实例
- Linux查看硬件信息以及驱动设备的命令
- OpenGL ES之GLSurfaceView学习四:Android Demo里的Cube分析