http://poj.org/problem?id=3468

题意:

给出一串数,每次在一个区间内增加c,查询[a,b]时输出a、b之间的总和。

思路:

总结一下懒惰标记的用法吧。

比如要对一个区间范围内的数都要加c,在找到这个区间之后,本来它的孩子结点也是需要更新的,但是我们可以暂时不更新,如果到时候需要用到这些孩子结点的时候,我们再来更新。这个时候就要用到懒惰标记了,也就是add[o]=c,之后它的孩子结点更新时就只需要加上add[o]就可以了。

  1 #include<iostream>
  2 #include<string>
  3 #include<cstring>
  4 #include<cstdio>
  5 using namespace std;
  6
  7 const int maxn = 100000 + 10;
  8 int n, m;
  9
 10 long long add[maxn << 2];
 11 long long sum[maxn << 2];
 12
 13 void PushDown(int o, int m)
 14 {
 15     if (add[o])
 16     {
 17         //传递懒惰标记
 18         add[o << 1] += add[o];
 19         add[o << 1 | 1] += add[o];
 20         //更新子节点的值
 21         sum[o << 1] += add[o] * (m - (m >> 1));
 22         sum[o << 1 | 1] += add[o] * (m >> 1);
 23         //出去懒惰标记
 24         add[o] = 0;
 25     }
 26 }
 27
 28 void PushUp(int o)
 29 {
 30     sum[o] = sum[o << 1] + sum[o << 1 | 1];
 31 }
 32
 33 void build(int L, int R, int o)
 34 {
 35     add[o] = 0;
 36     if (L == R)
 37     {
 38         scanf("%lld", &sum[o]);
 39         return;
 40     }
 41     int mid = (L + R) / 2;
 42     build(L, mid, 2 * o);
 43     build(mid + 1, R, 2 * o + 1);
 44     PushUp(o);
 45 }
 46
 47 void update(int L, int R, int x, int l,int r,int o)
 48 {
 49     if (L <= l && R >= r)   //如果找到区间了,则不需要往下更新孩子结点了,等下次需要时再更新
 50     {
 51         add[o] += x;
 52         sum[o] += (r - l + 1)*x;
 53         return;
 54     }
 55     PushDown(o, r - l + 1);
 56     int mid = (l + r) / 2;
 57     if (L <= mid)
 58         update(L, R, x, l, mid, 2 * o);
 59     if (R > mid)
 60         update(L, R, x, mid + 1, r, 2 * o + 1);
 61     PushUp(o);
 62 }
 63
 64 long long query(int L, int R, int l, int r, int o)
 65 {
 66     if (L <= l && R >= r)
 67         return sum[o];
 68     PushDown(o, r - l + 1);
 69     int mid = (l + r) / 2;
 70     long long ans = 0;
 71     if (L <= mid)
 72         ans += query(L, R, l, mid, 2 * o);
 73     if (R > mid)
 74         ans += query(L, R, mid + 1, r, 2 * o + 1);
 75     return ans;
 76 }
 77
 78
 79 int main()
 80 {
 81     //freopen("D:\\txt.txt", "r", stdin);
 82     while (~scanf("%d%d", &n, &m))
 83     {
 84         build(1, n, 1);
 85         char c[5];
 86         int x, y, z;
 87         while (m--)
 88         {
 89             scanf("%s", &c);
 90             if (c[0] == 'Q')
 91             {
 92                 scanf("%d%d", &x, &y);
 93                 printf("%lld\n", query(x, y, 1, n, 1));
 94             }
 95             else
 96             {
 97                 scanf("%d%d%d", &x, &y, &z);
 98                 update(x, y, z, 1, n, 1);
 99             }
100         }
101     }
102 }

转载于:https://www.cnblogs.com/zyb993963526/p/6561795.html

POJ 3468 A Simple Problem with Integers(线段树:区间更新)相关推荐

  1. POJ 3468 A Simple Problem with Integers(线段树区间更新)

    题目链接 这个真费劲...其实我也不懂 为什么...大体思想是,如果把区间更新了,开始的时候只把用懒惰标记标记那个区间,而不更新底层元素,而如果查询的时候顺带着把lz标记给消除...多敲几遍,多调试一 ...

  2. poj 3468 A Simple Problem with Integers(线段树区区)

    题目链接:  http://poj.org/problem?id=3468 题目大意:  给出N个数,和M次查询 C a b c  区间[a,b]的值都加上c Q a b     查询区间[a,b]值 ...

  3. 【线段树】【模板】讲解 + 例题1 HDU - 1754 I Hate It (点修改分数)+ 例题二 POJ - 3468 A Simple Problem with Integers(区间加值)

    [线段树][模板]讲解 + 例题1 HDU - 1754 I Hate It (点修改分数)+ 例题二 POJ - 3468 A Simple Problem with Integers(区间加值) ...

  4. POJ 3468 A Simple Problem with Integers

    分析:这题wa了好多次(看了下discuss好多人也是这样,好题~).一处是sum值会超int32,要用int64.还有一处是toadd要累加,我不知道是受上一题影响还是怎的..pushdown的时候 ...

  5. POJ 3468 A Simple Problem with Integers (1)

    POJ_3468(1) 在消化了PPT上思想之后,又重新做了一下这个题目. 不妨将原数组的元素记作a[i],然后我们用堆建立两棵线段树,一棵的原数组为x[i](x[i]=a[i]-a[i-1],即原数 ...

  6. POJ 2528 Mayor's posters 贴海报 线段树 区间更新

    注意离散化!!!线段树的叶子结点代表的是一段!!! 给出下面两个简单的例子应该能体现普通离散化的缺陷: 1-10 1-4 5-10 1-10 1-4 6-10 普通离散化算出来的结果都会是2,但是第二 ...

  7. POJ - 3468 A Simple Problem with Integers(分块)

    题目链接:点击查看 题目大意:给出一个长度为 n 的数列,再给出 m 次操作,每次操作分为两种情况: C l r d:区间 [ l , r ] 内的数字都加上 d Q l r :查询 [ l , r ...

  8. poj 3486 A Simple Problem with Integers(树状数组第三种模板改段求段)

    1 /* 2 树状数组第三种模板(改段求段)不解释! 不明白的点这里:here! 3 */ 4 #include<iostream> 5 #include<cstring> 6 ...

  9. POJ 2777 ZOJ 1610 HDU 1698 --线段树--区间更新

    直接将这3题 放一起了  今天在做线段树的东西 这3个都是区间更新的 查询方式互相不同 反正都可以放到一起吧 直接先上链接了 touch me touch me touch me 关于涉及到区间的修改 ...

最新文章

  1. Delphi异常处理总结
  2. IQueryable和IQueryProvider初尝
  3. nginx 端口没有被占用启动闪退_Nginx 的简单使用 (IIS,Asp.Net) - 奋斗的中年人哈哈哈...
  4. python widnows mysql_Windows下python安装MySQLdb
  5. jpg怎么合成一份_海外商标注册申请程序复杂吗?应该怎么注册?
  6. EasyUI:easyUI中自定义icon
  7. opencv函数之saturate_cast(防止溢出)
  8. windows对应字体
  9. linux命令 dstat,dstat命令
  10. win2008Server 部署网站
  11. 表格内容如何合并在一起
  12. minecraft_如何使用MCEdit加快Minecraft的构建
  13. Swoole vs Workman
  14. 前端 day02 CSS
  15. UART和RS232/RS485的关系是什么?RS485在linux下的调试 ubuntu串口调试工具
  16. 求真值表,主析取范式,主合取范式
  17. IDEA常用快捷键(四)--查找文件、查找类
  18. 最新emoji表情代码大全_周六最美早晨好问候语图片大全 早晨好图片祝福 最新早上好问候动态表情图片...
  19. Web3能否撕裂国内 VC 的共识?
  20. php设置用户头像,php制作圆形用户头像的实例_自定义封装类源代码

热门文章

  1. python基本语法1.2--数的移位及与或抑或相关计算
  2. Feather包实现数据框快速读写,你值得拥有
  3. 【概率与期望】[UVA11021]Tribles
  4. Rails之格式化价格方法
  5. [转载]数据结构笔试题基础
  6. 微小宝公众号排行榜_排行榜 | 山西省高校、高职中专微信公众号周数据排行榜...
  7. 1. ThreadPoolExecutor的一个常用的构造方法
  8. python进程池:multiprocessing.pool
  9. python爬虫网络出错怎么办_Python爬虫常见问题
  10. elementUI vxe-table结合使用(通用表格)