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 ;
}

codevs 1082 线段树区间求和的更多相关文章

  1. codevs 1082 线段树练习 3(区间维护)

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

  2. POJ 2823 Sliding Window 线段树区间求和问题

    题目链接 线段树区间求和问题,维护一个最大值一个最小值即可,线段树要用C++交才能过. 注意这道题不是求三个数的最大值最小值,是求k个的. 本题数据量较大,不能用N建树,用n建树. 还有一种做法是单调 ...

  3. codevs 1082 线段树练习3

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

  4. Codevs 1082 线段树练习 3

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

  5. POJ3468(线段树区间求和+区间查询)

    https://vjudge.net/contest/66989#problem/C You have N integers, A1, A2, ... , AN. You need to deal w ...

  6. 【树状数组区间修改区间求和】codevs 1082 线段树练习 3

    http://codevs.cn/problem/1082/ [AC] #include<bits/stdc++.h> using namespace std; typedef long ...

  7. codevs 1082 线段树练习 3 区间更新+延迟标记

    题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 Input Description 第一行一个正整数n,接下 ...

  8. hdu 1116 敌兵布阵 线段树 区间求和 单点更新

    线段树的基本知识可以先google一下,不是很难理解 线段树功能:update:单点增减 query:区间求和 #include <bits/stdc++.h> #define lson ...

  9. codevs 1299 线段树 区间更新查询

    1299 切水果  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master 题解  查看运行结果     题目描述 Description 简单的说,一共N个水果排成 ...

随机推荐

  1. MySQL升级

    MySQL的升级相对来说还是比较简单的. 它支持两种方式的升级: 原地升级(In-place Upgrade) 关闭数据库,替换旧的二进制文件,重启数据库,执行mysql_upgrade 逻辑升级(L ...

  2. Vertica 安装,建库,新建测试用户并授予权限,建表,入库

    测试环境:RHEL 6.4 + Vertica 6.1.3-7 需求:搭建Vertica数据库3节点的测试环境,建立测试用户,建表,测试数据入库. 1.各节点关闭防火墙和SELinux,配置主机名,I ...

  3. IIS7.5上的REST服务的Put,Delete操作发生HTTP Error 405.0 - Method Not Allowed 解决方法

    WebDAV 是超文本传输协议 (HTTP) 的一组扩展,为 Internet 上计算机之间的编辑和文件管理提供了标准.利用这个协议用户可以通过Web进行远程的基本文件操作,如拷贝.移动.删除等.在I ...

  4. centos7查看系统版本,查看机器位数x86-64

    前言 由于不经常使用linux,每当使用的时候就是安装软件,安装软件的时候就要选择安装包平台,是32位的还是64位的.这时候突然发现不知道怎么查,于是百度.虽然轻而易举百度出来,但仍旧没有自己的笔记看 ...

  5. Less使用心得

    初识less就被其函数式编程css深深吸引了,而函数式编写css带来的好处不言而喻,复用,复用,还是复用.话不多说下面简单介绍下个人使用less的心得 首先网上有很多less的安装教程,这边不多做介绍 ...

  6. redis成长之路——(四)

    加强redis连接的连接池 虽然StackExchange.Redis针对连接已经做了很多工作,不过在实际应用场景中还是不够的,比如多实例的vip就会导致只能连到其中一个实例上等:本实例中的连接池只能 ...

  7. 让linux开机默认开启小键盘

     linux默认开机不开启数字键盘numberlock,每次输入开机密码还得劳烦自己去点亮指示灯,让此灯开机自动点亮,需要一个软件才行,就是numlockx了,可以通过yum安装:yuminstall ...

  8. Spring下ActiveMQ实战

    MessageQueue是分布式的系统里经常要用到的组件,一般来说,当需要把消息跨网段.跨集群的分发出去,就可以用这个.一些典型的示例就是: 1.集群A中的消息需要发送给多个机器共享: 2.集群A中消 ...

  9. Eclipse "Unable to install breakpoint due to missing line number attributes..."

    Eclipse 无法找到 该 断点,原因是编译时,字节码改变了,导致eclipse无法读取对应的行了 1.ANT编译的class Eclipse不认,因为eclipse也会编译class.怎么让它们统 ...

  10. PHP 适配器模式

    适配器模式(Adapter)模式:将一个类的接口,转换成客户期望的另一个类的接口.适配器让原本接口不兼容的类可以合作无间.     [适配器模式中主要角色]目标(Target)角色:定义客户端使用的与 ...