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

典型的一道基于lazy传递的线段树题目,这题和一般题目不同的地方在于,它的每次操作不是简单的覆盖线段,而是累加。记得第一次写的时候纠结了好久。

好的,既然是累加,那么如何传递lazy呢?答案是传递累加值!

为线段树加一个add域,表示该线段需要加几。如果某区间的add不为0,那么就将该区间的add传递给其子区间,并且跟新子区间的sum_val值。

解这题最关键的就是要能够分清楚啥东西要传递,传递下去将有什么影响,其他的都好说!整体来说还是蛮轻松的

View Code

  1 #include<iostream>  2 #include<string>  3 #include<algorithm>  4 using namespace std;  5   6 struct node  7 {  8     int l;  9     int r; 10     __int64 add; 11     __int64 sum_val; 12 }; 13  14 node tree[500000]; 15 int n,m; 16 __int64 num[100001]; 17  18 void build(int i,int l,int r) 19 { 20     tree[i].l=l; 21     tree[i].r=r; 22     tree[i].add=0; 23     if(l==r) 24     { 25         tree[i].sum_val=num[l]; 26         return; 27     } 28     int mid=(l+r)/2; 29     build(2*i,l,mid); 30     build(2*i+1,mid+1,r); 31     tree[i].sum_val=tree[2*i].sum_val+tree[2*i+1].sum_val; 32 } 33  34 void updata(int i,int l,int r,__int64 w) 35 { 36     if(tree[i].l>r || tree[i].r<l) 37         return; 38     if(tree[i].l>=l && tree[i].r<=r) 39     { 40         tree[i].add+=w;  //注意是+=,因为这不是简单的覆盖 41         tree[i].sum_val+=(tree[i].r-tree[i].l+1)*w; //由于区间所有的值都需要加上w,那么自然整段区间就是加上(w*区间大小)了 42         return; 43     } 44     if(tree[i].add!=0) 45     { 46         tree[2*i].add+=tree[i].add; //同上,注意是+= 47         tree[2*i+1].add+=tree[i].add; 48         tree[2*i].sum_val+=(tree[2*i].r-tree[2*i].l+1)*tree[i].add; 49         tree[2*i+1].sum_val+=(tree[2*i+1].r-tree[2*i+1].l+1)*tree[i].add; 50         tree[i].add=0; 51     } 52     updata(2*i,l,r,w); 53     updata(2*i+1,l,r,w); 54     tree[i].sum_val=tree[2*i].sum_val+tree[2*i+1].sum_val; //回溯跟新 55 } 56  57 __int64 ans; 58 void find(int i,int l,int r) 59 { 60     if(tree[i].l>r || tree[i].r<l) 61         return; 62     if(tree[i].l>=l && tree[i].r<=r) 63     { 64         ans+=tree[i].sum_val; 65         return; 66     } 67     if(tree[i].add!=0) 68     { 69         tree[2*i].add+=tree[i].add; 70         tree[2*i+1].add+=tree[i].add; 71         tree[2*i].sum_val+=(tree[2*i].r-tree[2*i].l+1)*tree[i].add; 72         tree[2*i+1].sum_val+=(tree[2*i+1].r-tree[2*i+1].l+1)*tree[i].add; 73         tree[i].add=0; 74     } 75     find(2*i,l,r); 76     find(2*i+1,l,r); 77 } 78  79 int main() 80 { 81     int i,a,b; 82     __int64 w; 83     char c; 84     freopen("in.txt","r",stdin); 85     while(scanf("%d%d",&n,&m)==2) 86     { 87         for(i=1;i<=n;i++) 88         { 89             scanf("%I64d",&num[i]); 90         } 91         build(1,1,n); 92         for(i=0;i<m;i++) 93         { 94             getchar(); 95             scanf("%c",&c); 96             if(c=='Q') 97             { 98                 scanf("%d%d",&a,&b); 99                 ans=0;100                 find(1,a,b);101                 printf("%I64d\n",ans);102             }103             else104             {105                 scanf("%d%d%I64d",&a,&b,&w);106                 updata(1,a,b,w);107             }108         }109     }110     return 0;111 }

转载于:https://www.cnblogs.com/ka200812/archive/2011/11/09/2243657.html

线段树专辑—— pku 3468 A Simple Problem with Integers相关推荐

  1. 【线段树】【模板】讲解 + 例题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(区间加值) ...

  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. 线段树专辑——pku 2886 Who Gets the Most Candies?

    http://poj.org/problem?id=2886 恩,分糖果,快乐的童年啊! 题目意思大概n个小孩围成一个圈,每个小孩手里有张卡片,记录着一个数字.开始从第k个孩子,该孩子离开圈子,然后告 ...

  4. 线段树专辑 —— pku 2482 Stars in Your Window

    http://poj.org/problem?id=2482 A了这题后,我就在想,是不是ACMER都找不到女朋友..... 这题看似很新颖,其实就是求线段树区间最值.所谓区间最值,其实就是和RMQ差 ...

  5. 线段树专辑——pku 3667 Hotel

    http://poj.org/problem?id=3667 哈哈,经典中的经典题啊.利用线段树求最大连续空闲区间,并返回空闲区间的起点坐标. View Code 1 #include<iost ...

  6. POJ 3468 A Simple Problem with Integers

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

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

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

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

    http://poj.org/problem?id=3468 题意: 给出一串数,每次在一个区间内增加c,查询[a,b]时输出a.b之间的总和. 思路: 总结一下懒惰标记的用法吧. 比如要对一个区间范 ...

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

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

最新文章

  1. html:漂亮的原生表格_HTML表格:关于它们的所有知识
  2. winform实现翻书效果_如何用PPT实现翻书效果?
  3. [BUUCTF-pwn]——jarvisoj_level2
  4. 如何免费申请并使用SAP Marketing Cloud测试系统
  5. Struts入门(三)深入Struts用法讲解
  6. java spring druid_Spring配置Druid连接池
  7. 高中计算机教师招聘试题,中小学信息技术教师招聘考试真题及答案.doc
  8. 列举python中常用的数据类型_Python基础知识 变量和简单数据类型
  9. android java 指针异常处理,Android自定义抛出异常的方法详解
  10. 企业搜索引擎(Enterprise Search Engine)的2007中重要的功能
  11. Docker常见问题
  12. python单词的含义-python
  13. Web UI设计师的CSS优化工具 25+
  14. 【细胞分割】基于matlab GUI形态学算法红细胞计数【含Matlab源码 638期】
  15. 有意义的100个小故事
  16. 工程伦理期末考试答案(学堂云雨课堂)
  17. Dymola — 多学科系统仿真平台
  18. 中信证券java面试_中信证券面试问题分享
  19. Total Phase Data Center介绍
  20. 用友致远A6协同管理软件操作手册

热门文章

  1. java lambda 变量_java – 从lambda表达式引用的局部变量必须...
  2. 移动超级sim卡 无法下载卡_共迎未来无限可能!5G超级SIM卡亮相2019中国移动全球合作伙伴大会...
  3. c# u盘使用记录_金属U盘定制加工 各种款式金属U盘加工
  4. 设计模式(一)----简单工厂、工厂方法和抽象工厂区别
  5. C#将DataTable海量数据导出到Excel
  6. rtl8812au linux驱动下载,Ubuntu 16.04 安装 rtl8812au系列 (DWA-182) wireless adapter driver
  7. 组装自己的php框架,搭建自己的PHP框架
  8. python成员变量,成员函数的总结
  9. Spring Boot AOP的使用
  10. Spark SQL External DataSource外部数据源