poj3468 A Simple Problem with Integers(成段更新)
2016-05-15 21:57
316 查看
http://poj.org/problem?id=3468
题意:给你n个数q个操作,q查询,c为某一段内的值增加一定的增幅。
思路:本来想自己敲出lazy,失败了。。看了别人的,增加add域,在查询和更新区间内每次判断该节点是否有增量。若有,则说明递归到了此节点,但不是所求的区间,也就没有价值了,将价值传递给儿子节点,add和sum同时更新。这里sum求和时,每次都是在原有的基础上增加增量*节点数。其余感觉也没什么,但为毛自己就是敲不出来。。。
题意:给你n个数q个操作,q查询,c为某一段内的值增加一定的增幅。
思路:本来想自己敲出lazy,失败了。。看了别人的,增加add域,在查询和更新区间内每次判断该节点是否有增量。若有,则说明递归到了此节点,但不是所求的区间,也就没有价值了,将价值传递给儿子节点,add和sum同时更新。这里sum求和时,每次都是在原有的基础上增加增量*节点数。其余感觉也没什么,但为毛自己就是敲不出来。。。
#include <stdio.h> #include <algorithm> #include <stdlib.h> #include <string.h> #include <iostream> using namespace std; const int N = 100010; const int INF = 1e8; struct line//线段树节点 { int l, r;//左右端点 __int64 sum;//节点总和 __int64 add;//增量 }tree[4*N]; __int64 a0 ; void build(int i, int l, int r) { tree[i].l = l; tree[i].r = r; tree[i].add = 0; if(l == r) { tree[i].sum = a0[l]; return; } int mid = (l+r) >> 1; build(i*2, l, mid); build(i*2+1, mid+1, r); tree[i].sum = tree[i*2].sum+tree[i*2+1].sum; } void update(int i, int l, int r, __int64 add) { tree[i].sum += (r-(l-1))*add; if(tree[i].l == l && tree[i].r == r) { tree[i].add += add; return; } if(tree[i].add) { tree[i*2].add += tree[i].add; tree[i*2+1].add += tree[i].add; tree[i*2].sum += tree[i].add*(tree[i*2].r-(tree[i*2].l-1)); tree[i*2+1].sum += tree[i].add*(tree[i*2+1].r-(tree[i*2+1].l-1)); tree[i].add = 0; } int mid = (tree[i].l+tree[i].r) >> 1; if(mid >= r) update(i*2, l, r, add); else if(mid < l) update(i*2+1, l, r, add); else { update(i*2, l, mid, add); update(i*2+1, mid+1, r, add); } } __int64 query(int i, int l, int r) { if(tree[i].l == l && tree[i].r == r) { return tree[i].sum; } if(tree[i].add) { tree[i*2].add += tree[i].add; tree[i*2+1].add += tree[i].add; tree[i*2].sum += tree[i].add*(tree[i*2].r-(tree[i*2].l-1)); tree[i*2+1].sum += tree[i].add*(tree[i*2+1].r-(tree[i*2+1].l-1)); tree[i].add = 0; } int mid = (tree[i].l+tree[i].r) >> 1; if(mid >= r) return query(i*2, l, r); else if(mid < l) return query(i*2+1, l, r); else { return query(i*2, l, mid)+query(i*2+1, mid+1, r); } } int main() { // freopen("in.txt", "r", stdin); int n, q, a, b; __int64 c; char s[5]; scanf("%d%d", &n, &q); for(int i = 1; i <= n; i++) { scanf("%I64d", &a0[i]); } build(1, 1, n); for(int i = 1; i <= q; i++) { scanf("%s", s); if(s[0] == 'Q') { scanf("%d%d", &a, &b); printf("%I64d\n", query(1, a, b)); } else if(s[0] == 'C') { scanf("%d%d%I64d", &a, &b, &c); update(1, a, b, c); } } return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2159 Ancient Cipher
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- POJ1050 最大子矩阵和
- 用单调栈解决最大连续矩形面积问题
- 2632 Crashing Robots的解决方法
- 1573 Robot Motion (简单题)