POJ 3468 A Simple Problem with Integers(线段树成段更新)
2015-03-31 21:31
483 查看
题意:
给出点集数以及命令数;先将每一个点赋初值
Q a b 表示求出点集中从a到b的和
C a b c 表示将a到b的点全部加c
解析:
线段树,并且单纯的线段树会超时,因为在将a到b的点全部加上c时,步骤太多,会超时。需要优化。即Lazy算法;Lazy算法:
在将 ql ~ qr 点全部加 val 时,不要加到每个点,在表示区间的 root 结构体上增加一个addv域,将要加的值赋给这个addv域,然后就不要再往下了。在求区间和时,将root中的 addv 值赋给要求的区间,并且将该节点的root置零。
AC代码
[code]#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <cstdlib> #define ls o*2 #define rs o*2+1 using namespace std; typedef __int64 ll; const int INF = 0x3f3f3f3f; const int N = 1e5 + 10; ll addv[N<<2], sumv[N<<2], a ; inline void maintain(int o, int L, int R) { sumv[o] = 0; if(R > L) { sumv[o] = sumv[ls] + sumv[rs]; } sumv[o] += addv[o] * (R-L+1); } void build(int o, int L, int R) { if(L == R) { sumv[o] = addv[o] = a[L]; return ; } int M = (L+R)/2; build(ls, L, M); build(rs, M+1, R); maintain(o, L, R); } int ql, qr, val; void modify(int o, int L, int R) { if(ql <= L && R <= qr) { addv[o] += val; }else { int M = (L+R)/2; if(ql <= M) modify(ls, L, M); if(qr > M) modify(rs, M+1, R); } maintain(o, L, R); } ll _sum; void query(int o, int L, int R, ll add) { if(ql <= L && R <= qr) { _sum += sumv[o] + add*(R-L+1); }else { int M = (L+R)/2; if(ql <= M) query(ls, L, M, add+addv[o]); if(qr > M) query(rs, M+1, R, add+addv[o]); } } int main() { int n, q; char cmd[4]; while(scanf("%d%d", &n, &q) != EOF) { for(int i = 1; i <= n; i++) scanf("%I64d", &a[i]); build(1, 1, n); while(q--) { scanf("%s", cmd); if(cmd[0] == 'Q') { scanf("%d%d", &ql, &qr); _sum = 0; query(1, 1, n, 0); printf("%I64d\n", _sum); }else if(cmd[0] == 'C') { scanf("%d%d%d", &ql, &qr, &val); modify(1, 1, n); } } } 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(线段树成段更新lazy)
- poj 3468 A Simple Problem with Integers(线段树成段更新,延迟标记,Lazy)
- [ACM] 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?(线段树成段更新求和)
- [ACM] 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 线段树成段更新+区间查询
- [ACM] poj 3468 A Simple Problem with Integers(线段树,成段更新,懒惰标记)
- poj 3468 A Simple Problem with Integers 【线段树成段更新 + 区间求和】
- 线段树 POJ 3468 A Simple Problem with Integers 线段树 成段更新入门