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的时候才标记下放。如果不这样,本来一个对的值就会被重新计算,从而破坏了线段树的性质。

附上代码:

 #include<cstdio>
#include<iostream>
#define LL long long int
using namespace std;
const int maxn=; LL n,k,A[maxn],sumv[maxn*],addv[maxn*]; void init(int o,int L,int R)//初始化建树
{
if(L==R) sumv[o]=A[L];
else
{
int M=(L+R)/;
init(o*,L,M);
init(o*+,M+,R);
sumv[o]=sumv[o*]+sumv[o*+];
}
} void pushdown(int o,int L,int R)//标记下放
{
int M=(L+R)/;
if(L!=R) sumv[o]=sumv[o*]+sumv[o*+]+addv[o]*(R-L+)+addv[o*]*(M-L+)+addv[o*+]*(R-M);
else sumv[o]+=addv[o];
addv[o*]+=addv[o];
addv[o*+]+=addv[o];
addv[o]=;
} int y1,y2,v;
void update(int o,int L,int R)//更新
{
if(y1<=L && R<=y2) addv[o]+=v;
else
{
int M=(L+R)/;
if(y1<=M) update(o*,L,M);
if(y2>M) update(o*+,M+,R);
}
pushdown(o,L,R);
} LL _sum,p;
void query(int o,int L,int R)//查询
{
if(addv[o]!=) pushdown(o,L,R);
if(y1<=L && R<=y2) _sum+=sumv[o];
else
{
int M=(L+R)/;
if(y1<=M) query(o*,L,M);
if(y2>M) query(o*+,M+,R);
}
} int main()
{
cin>>n;
for(int i=;i<=n;i++) cin>>A[i];
init(,,n);
cin>>k;
for(int i=,tp,x,y,z;i<=k;i++)
{
cin>>tp;
if(tp==)
{
cin>>x>>y>>z;
y1=x,y2=y,v=z;
update(,,n);
}
else
{
cin>>x>>y;
y1=x,y2=y,_sum=;
query(,,n);
cout<<_sum<<endl;
}
}
return ;
}

最新文章

  1. JS事件的三种方式
  2. 8.Struts2类型转换器
  3. 【Java】JavaWeb权限管理
  4. iOS不得姐项目--图片帖子模块,大图默认显示最顶部分的处理
  5. Eclipse: The superclass “javax.servlet.http.HttpServlet” was not found on the Java Build Path
  6. linux下安装openssh-server
  7. CI(CodeIgniter)框架介绍
  8. C# webbrowser 修改useragent
  9. android真机自动化测试
  10. c++ THUNK技术
  11. Ubuntu12.04 下修改Apache端口号
  12. poj 1503 大数相加(java)
  13. php之文件基础操作
  14. php中cookie和session的总结
  15. 利用travis自动化构建与部署(文档项目)
  16. eclipse中没有tomcat小猫
  17. 面试题-----按位翻转32位unsigned
  18. linux:根据名称杀死进程
  19. shell随笔
  20. asp.net mvc中DropDownList

热门文章

  1. 设计模式(十二):通过ATM取款机来认识“状态模式”(State Pattern)
  2. YunCart电商网站支付宝接口出现500错误
  3. 利用C#开发移动跨平台Hybrid App(一):从Native端聊Hybrid的实现
  4. 6.C#WinForm基础城市选择器
  5. 利用Python进行数据分析(1) 简单介绍
  6. WPF 后台数据触发改变界面状态-心跳实现
  7. java.lang.Class.isAssignableFrom()用法解析
  8. Python ZIP 文件创建与读取
  9. linux中输入输出和重定向问题
  10. nginx+lua