codevs 1082 线段树练习3

链接:http://codevs.cn/problem/1082/

sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值。

我的线段树写法在运用的时候,需要更新或查找的区间是储存在y1,y2变量里面的,值是储存在变量v里面的,查询结果储存在变量_sum里面。

每次更新(调用update函数)时,必须要维护更新区间上层的线段树,即更新节点上面的线段树表示的和是准确的和。

在update函数更新的时候,如果线段树分成区间包含于所要求的区间那么直接在addv上记录下要加的值,否则再次细分区间。最后要再维护一下(调用pushdown函数),这样就保证了线段树的和性质。

pushdown函数非常重要,在我的写法里,它有两个作用,一个是标记下放,另一个是结算和维护。注意在结算和的时候,要把左右儿子的addv和的也要加上去,否则会漏值。查询的时候也要用到pushdown,否则addv的值会在细分区间的时候漏掉,但查询(query函数)的pushdown不太样,要加入一个判断:只有当addv值不为0的时候才标记下放。如果不这样,本来一个对的值就会被重新计算,从而破坏了线段树的性质。

附上代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #define LL long long int
 4 using namespace std;
 5 const int maxn=300010;
 6
 7 LL n,k,A[maxn],sumv[maxn*4],addv[maxn*4];
 8
 9 void init(int o,int L,int R)//初始化建树
10 {
11     if(L==R) sumv[o]=A[L];
12     else
13     {
14         int M=(L+R)/2;
15         init(o*2,L,M);
16         init(o*2+1,M+1,R);
17         sumv[o]=sumv[o*2]+sumv[o*2+1];
18     }
19 }
20
21 void pushdown(int o,int L,int R)//标记下放
22 {
23     int M=(L+R)/2;
24     if(L!=R) sumv[o]=sumv[o*2]+sumv[o*2+1]+addv[o]*(R-L+1)+addv[o*2]*(M-L+1)+addv[o*2+1]*(R-M);
25     else sumv[o]+=addv[o];
26     addv[o*2]+=addv[o];
27     addv[o*2+1]+=addv[o];
28     addv[o]=0;
29 }
30
31 int y1,y2,v;
32 void update(int o,int L,int R)//更新
33 {
34     if(y1<=L && R<=y2) addv[o]+=v;
35     else
36     {
37         int M=(L+R)/2;
38         if(y1<=M) update(o*2,L,M);
39         if(y2>M) update(o*2+1,M+1,R);
40     }
41     pushdown(o,L,R);
42 }
43
44 LL _sum,p;
45 void query(int o,int L,int R)//查询
46 {
47     if(addv[o]!=0) pushdown(o,L,R);
48     if(y1<=L && R<=y2) _sum+=sumv[o];
49     else
50     {
51         int M=(L+R)/2;
52         if(y1<=M) query(o*2,L,M);
53         if(y2>M) query(o*2+1,M+1,R);
54     }
55 }
56
57 int main()
58 {
59     cin>>n;
60     for(int i=1;i<=n;i++) cin>>A[i];
61     init(1,1,n);
62     cin>>k;
63     for(int i=1,tp,x,y,z;i<=k;i++)
64     {
65         cin>>tp;
66         if(tp==1)
67         {
68             cin>>x>>y>>z;
69             y1=x,y2=y,v=z;
70             update(1,1,n);
71         }
72         else
73         {
74             cin>>x>>y;
75             y1=x,y2=y,_sum=0;
76             query(1,1,n);
77             cout<<_sum<<endl;
78         }
79     }
80     return 0;
81  }

转载于:https://www.cnblogs.com/frankscode/p/6239091.html

codevs 1082 线段树区间求和相关推荐

  1. [Codevs] 1082 线段树练习3

    1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的 ...

  2. 牛客网 2018年全国多校算法寒假训练营练习比赛(第五场) H.Tree Recovery-完全版线段树(区间更新、区间求和)...

    H.Tree Recovery 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语言262144K 64bit IO Format: %lld 链接:https:/ ...

  3. Codeforces 444C DZY Loves Colors 线段树区间更新

    // Codeforces 444C DZY Loves Colors 线段树区间更新// 题目链接:// http://codeforces.com/problemset/problem/444/C ...

  4. 树链剖分——线段树区间合并bzoj染色

    线段树区间合并就挺麻烦了,再套个树链就更加鬼畜,不过除了代码量大就没什么其他的了.. 一些细节:线段树每个结点用结构体保存,pushup等合并函数改成返回一个结构体,这样好写一些 struct Seg ...

  5. SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并

    Can you answer these queries III SPOJ - GSS3 这道题和洛谷的小白逛公园一样的题目. 传送门: 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间 ...

  6. CF911G Mass Change Queries (线段树区间 合并)

    题意: 给出一个数列,有q个操作,每种操作是把区间[l,r]中等于x的数改成y.输出q步操作完的数列. 题解: 100个数,很容易想到要从这里进行突破,对于某次操作我们只需要把这个区间的数x给移动到y ...

  7. hdu 5692 Snacks(dfs序+线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5692 解题思路:这道题是树节点的点权更新,而且涉及到子树,常用的思路是利用dfs序,用线段树来对区间进 ...

  8. hdu 1698(线段树区间更新)

    解题思路:线段树区间更新水题. #include<iostream> #include<cstdio> #include<cstring> using namesp ...

  9. Tunnel Warfare(HDU1540+线段树+区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540 题目: 题意:总共有n个村庄,有q次操作,每次操作分为摧毁一座村庄,修复一座村庄,和查询与询问的 ...

最新文章

  1. linux c 启动程序吗,Linux下C程序启动时的系统调用
  2. 修改Kali Linux 2020.1主题颜色
  3. Linux16.04配置CUDA8.0+CUDNNV5.1
  4. AI算法连载14:统计之模型选择
  5. Mac彻底删除WebStorm
  6. 有关数组知识点的小结
  7. git命令行常用操作及在linux下push到github项目中遇到的问题
  8. Python细节面试题--小整数对象池和大整数对象池
  9. 数字逻辑_逻辑函数化简(配项法)例子
  10. 好券零购4.0开发笔记
  11. 查看PDF文件的字体格式
  12. 手把手教你 VSCode搭建STM32开发环境
  13. 虚拟服务器和vdi,如何搭建高效虚拟桌面架构(VDI)
  14. 微信公众号主体注册数量提升申请方法
  15. 三十六计之借刀杀人(第三计)
  16. [CTS2019]氪金手游(容斥+树形背包DP)
  17. 江苏农村商业银行计算机类笔试考什么时候,2020江苏农商行春季校园招聘笔试考什么?...
  18. 【excel】利用NETWORKDAYS.INTL函数计算两日期之间的工作日时间
  19. 在云服务器重装系统后vscode连不上服务器的解决
  20. 【黑马程序员pink老师前端】CSS

热门文章

  1. 判断鼠标点击在div外时,更改背景图片
  2. [转] 鼠标移入/移出颜色渐变
  3. NHibernate之旅(10):探索父子(一对多)关联查询
  4. 【JLOI2011】飞行路线
  5. BZOJ4241 历史研究(莫队)
  6. 移动端省际联动插件mobiscroll
  7. 2017.7.6 linux 搭建ssh服务器 scp
  8. [hive学习翻译]Hive - Introduction
  9. 窥探try ... catch与__try ... __except的区别
  10. 渣渣小本求职复习之路每天一博客系列——TCP/IP协议栈(5)