poj 3468 A Simple Problem with Integers (线段树 成段更新 加值 求和)
2014-08-07 10:35
393 查看
题目链接
题意:
只有这两种操作
C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
代码风格更新后:
代码风格更新前:
分析:自己写的有点麻烦了,写的时候手残+脑残,改了好久。
val+lazy*(r-l+1)表示和,如果lazy==0表示当前区间加的值不统一。
题意:
只有这两种操作
C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
代码风格更新后:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #define lson l, mid, 2*rt #define rson mid+1, r, 2*rt+1 #define LL __int64 const int maxn = 100000+10; using namespace std; LL sum[4*maxn], lz[4*maxn]; void pushup(int rt) { sum[rt] = sum[2*rt]+sum[2*rt+1]; } void pushdown(int l, int r, int rt) { if(lz[rt]!=0) { int mid = (l+r)/2; sum[2*rt] += lz[rt]*(mid-l+1); sum[2*rt+1] += lz[rt]*(r-mid); lz[2*rt] += lz[rt]; lz[2*rt+1] += lz[rt]; lz[rt] = 0; } } void build(int l, int r, int rt) { if(l==r) { scanf("%I64d", &sum[rt]); return; } int mid = (l+r)/2; build(lson); build(rson); pushup(rt); } void update(int ll, int rr, LL c, int l, int r, int rt) { if(ll>r) return; if(rr<l) return; if(ll<=l && rr>=r) { lz[rt] += c; sum[rt] += (r-l+1)*c; return; } pushdown(l, r, rt); int mid = (l+r)/2; update(ll, rr, c, lson); update(ll, rr, c, rson); pushup(rt); } LL query(int ll, int rr, int l, int r, int rt) { if(ll>r) return 0; if(rr<l) return 0; if(ll<=l && rr>=r) return sum[rt]; pushdown(l, r, rt); int mid = (l+r)/2; return query(ll, rr, lson)+query(ll, rr, rson); } int main() { int n, q, a, b; LL c; char ch; while(~scanf("%d%d", &n, &q)) { memset(sum, 0, sizeof(sum)); memset(lz, 0, sizeof(lz)); build(1, n, 1); while(q--) { getchar(); scanf("%c %d %d", &ch, &a, &b); if(ch=='Q') printf("%I64d\n", query(a, b, 1, n, 1)); else { scanf("%I64d", &c); update(a, b, c, 1, n, 1); } } } return 0; }
代码风格更新前:
分析:自己写的有点麻烦了,写的时候手残+脑残,改了好久。
val+lazy*(r-l+1)表示和,如果lazy==0表示当前区间加的值不统一。
#include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <cstdlib> #include <algorithm> #define LL __int64 const int maxn = 100000+10; using namespace std; int n, q; __int64 a[maxn]; struct line { int l, r; LL val, lazy; }tr[4*maxn]; void build(int o, int l, int r) { tr[o].l = l; tr[o].r = r; tr[o].lazy = 0; if(l==r) { tr[o].val = a[l]; return; } int mid = (l+r)/2; build(2*o, l, mid); build(2*o+1, mid+1, r); tr[o].val = tr[2*o].val+tr[2*o+1].val; } void update(int o, int l, int r, int add) { if(tr[o].l==l && tr[o].r==r) { tr[o].lazy += add; return; } if(tr[o].lazy) //之前没向下更新的向下更新 { tr[2*o].lazy += tr[o].lazy; tr[2*o+1].lazy += tr[o].lazy; tr[o].val += (LL)(tr[o].lazy*(tr[o].r-tr[o].l+1)); //同时把lazy存的加到和里 tr[o].lazy = 0; } tr[o].val += (LL)(add*(r-l+1)); //在这个过程中把新增加的加上,注意左右区间 int mid = (tr[o].l+tr[o].r)/2; if(r <= mid) update(2*o, l, r, add); else if(l > mid) update(2*o+1, l, r, add); else { update(2*o, l, mid, add); update(2*o+1, mid+1, r, add); } } LL query(int o, int l, int r) { if(tr[o].l==l && tr[o].r==r) return tr[o].val + tr[o].lazy*(r-l+1); if(tr[o].lazy) //由于之前可能存在 没有更新的所以向下更新 { tr[2*o].lazy += tr[o].lazy; tr[2*o+1].lazy += tr[o].lazy; tr[o].val += (LL)(tr[o].lazy*(tr[o].r-tr[o].l+1)); tr[o].lazy = 0; } int mid = (tr[o].l+tr[o].r)/2; if(r<=mid) return query(2*o, l, r); else if(l > mid) return query(2*o+1, l, r); else { return query(2*o, l, mid) + query(2*o+1, mid+1, r); } } int main() { int i, l, r, add; char ch; while(~scanf("%d%d", &n, &q)) { for(i = 1; i <= n; i++) scanf("%I64d", &a[i]); build(1, 1, n); for(i = 1; i <= q; i++) { getchar(); scanf("%c", &ch); if(ch=='Q') { scanf("%d%d", &l, &r); printf("%I64d\n", query(1, l, r)); } else { scanf("%d%d%d", &l, &r, &add); update(1, l, r, add); } } } return 0; }
相关文章推荐
- poj 3468 A Simple Problem with Integers 【线段树成段更新 + 区间求和】
- poj 3468 A Simple Problem with Integers(线段树)(第二部分 成段更新,区间求和)
- POJ 3468-A Simple Problem with Integers(线段树:成段更新,区间求和)
- POJ 3468 A Simple Problem with Integers(段更新的区间求和&Lazy思想&线段树)
- POJ 3468 A Simple Problem with Integers (线段树,成段更新,区间求和)
- POJ 题目3468 A Simple Problem with Integers(线段树成段更新,区间求和)
- POJ 3468 A Simple Problem with Integers?(线段树成段更新求和)
- 线段树(成段更新) 之 poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers(线段树,成段更新)
- 20140719 「线段树 - 区间更新,区间求和」 POJ 3468 A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers(线段树功能:区间加减区间求和)
- poj 3468 A Simple Problem with Integers(线段树|成段更新,区间查询)
- [ACM] poj 3468 A Simple Problem with Integers(线段树,成段更新,懒惰标记)
- [ACM] poj 3468 A Simple Problem with Integers(线段树,成段更新,懒惰标记)
- poj 3468:A Simple Problem with Integers(线段树,区间修改求和)
- poj 3468 A Simple Problem with Integers(线段树成段更新,延迟标记,Lazy)
- POJ 3468 A Simple Problem with Integers (线段树成段更新) 解题报告
- poj 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)
- POJ-3468-A Simple Problem with Integers(区间更新,求和)-splay或线段树
- POJ 3468:A Simple Problem with Integers(线段树[成段更新])