codevs 1080 线段树点修改
先来介绍一下线段树。
线段树是一个把线段,或者说一个区间储存在二叉树中。如图所示的就是一棵线段树,它维护一个区间的和。


蓝色数字的是线段树的节点在数组中的位置,它表示的区间已经在图上标出,它的值就是这段区间的和。
比如说线段树1号节点表示[1,5]区间,它的值是13,也就是原数组1号位到5号位所有数字加起来的和。
不难发现线段树的下标有这样的性质:
1. 设一个节点的下号是o,那么它的左子树是o*2,右子树是o*2+1。
2. 线段树的大小是原数组的大小*2-1。
3. 线段树叶节点表示区间的长度为1,也就是一个数字,此时区间的左边界=区间的右边界。
但是我们实际使用的时候,线段树是用一个长度为原数组大小4倍的数组储存的,因为方便处理,防止访问叶节点时下标越界。
它支持几种操作:
1. 修改一个点的值
2. 将一个区间加上或减去某个数
3. 查询一个区间的和(乘积也可以),最大/最小值
4. 将一个区间值改变成某个大于0的数
以上时间复杂度都是logn。
建立线段树:
这里我采用递归的方式。在函数内设3个参数,这个线段树节点的下标o,它表示的左区间L,又区间R。从根节点开始递归,如果L=R,就是走到了叶节点(根据性质3),那么该点就是原数组第L(或R)位的值,否则分成两个区间,递归它的左右子树。
代码如下:
void init(int o,int L,int R)
{
if(L==R) sumv[o]=A[L]; //A[]是原数组,sumv[]是线段树数组
else
{
int M=(L+R)/;
init(o*,L,M);
init(o*+,M+,R);
sumv[o]=sumv[o*]+sumv[o*+];
}
}
这里的sumv是求和线段树数组,我以这个为例。当然如果是维护区间最大/最小,那么第9行的代码应该是左右子树的最大/最小值。
调用:
init(1,1,n);
// 1,n是总区间。
点修改:
与建树的过程类似,从根节点开始,一直递归到叶节点,然后直接修改,完成之后,更新sumv值就可以了。
如果把修改原数组p号位的值修改为v。
代码:
int p,v; void update(int o,int L,int R)
{
if(L==R) sumv[o]=v;
else
{
int M=(L+R)/;
if(p<=M) update(o*,L,M); else update(o*+,M+,R);
sumv[o]=sumv[o*]+sumv[o*+];
}
}
调用:
先把p,和v赋值好,然后直接调用即可
p=x,v=y;//x,y是你要赋的值
update(1,1,n);
查询区间的和:
还是与上面类似。从根节点开始递归。如果这一层的区间[L,R]包含于要求的区间[y1,y2],那么就把这一层的值累加,否则就访问它的子树,把这个区间一份为二。
如果它的子树表示的区间与要求的区间有交集,就说明有需要访问,否则就不用。
代码:
int y1,y2,ans;
void query(int o,int L,int R)
{
if(y1<=L && R<=y2) ans+=sumv[o];
else
{
int M=(L+R)/;
if(y1<=M) query(o*,L,M);
if(y2>M) query(o*+,M+,R);
}
}
调用:
把要查找的区间y1,y2赋值好,并把存储答案的ans清0,,再调用即可
y1=x,y2=y,ans=0;//注意ans一定要初始化,最后查出来的答案是保存在ans里面的。
query(1,1,n);
点修改的说明就到此。
测试的题目:codevs 1080 线段树练习
链接:http://codevs.cn/problem/1080/
附代码:
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=; int A[maxn],sumv[maxn*],n,m; 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*+];
}
} int p,v;
void update(int o,int L,int R)
{
if(L==R) sumv[o]=v;
else
{
int M=(L+R)/;
if(p<=M) update(o*,L,M); else update(o*+,M+,R);
sumv[o]=sumv[o*]+sumv[o*+];
}
} int y1,y2,ans;
void query(int o,int L,int R)
{
if(y1<=L && R<=y2) ans+=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>>m;
for(int i=,k,x,y;i<=m;i++)
{
cin>>k>>x>>y;
if(k==)
{
p=x,v=A[p]+y;
A[p]=v;
update(,,n);
}
else
{
y1=x,y2=y,ans=;
query(,,n);
cout<<ans<<endl;
}
}
return ;
}
codevs 1080 线段树点修改的更多相关文章
- codevs 1080 线段树练习 CDQ分治
codevs 1080 线段树练习 http://codevs.cn/problem/1080/ 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 一行N个 ...
- codevs 1080 线段树练习--用树状数组做的
1080 线段树练习 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 一行N个方格,开始每个格子里都有一个整数.现在动态 ...
- Codevs 1080 线段树练习(CDQ分治)
1080 线段树练习 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 一行N个方格,开始每个格子里都有 ...
- codevs——1080 线段树练习
1080 线段树练习 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 一行N个方格,开始每个格子里都有 ...
- codevs 1080 线段树练习
链接:http://codevs.cn/problem/1080/ 先用树状数组水一发,再用线段树水一发 树状数组代码:84ms #include<cstdio> #include< ...
- Codevs 1080 线段树联系
题目描述 Description 一行N个方格,开始每个格子里都有一个整数.现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和:修改的规则是指定某一个格子x,加上或 ...
- codevs 1080 线段树练习(线段树)
题目: 题目描述 Description 一行N个方格,开始每个格子里都有一个整数.现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和:修改的规则是指定某一个格子x ...
- wikioi 1080 线段树练习 树状数组
1080 线段树练习 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 一行N个方格,开始每个格子里都有一个整数.现 ...
- codevs 1082 线段树练习 3(区间维护)
codevs 1082 线段树练习 3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...
随机推荐
- ITTC数据挖掘系统(六)批量任务,数据查看器和自由文档
这一次带来了一系列新特新,同时我们将会从商业智能的角度讨论软件的需求 一. 批量任务向导 一个常用的需求是完成处理多个任务,可能是同一个需求以不同的参数完成多次,这类似批量分析某一问题:或者是不同的需 ...
- Oracle 11.2.0.4 RAC安装最新PSU补丁
环境:两节点RAC(RHEL 6.4 + GI 11.2.0.4 + Oracle 11.2.0.4) 需求:安装最新PSU补丁11.2.0.4.7 1.下载补丁和最新OPatch 2.检查数据库当前 ...
- 中文分词工具探析(一):ICTCLAS (NLPIR)
1. 前言 ICTCLAS是张华平在2000年推出的中文分词系统,于2009年更名为NLPIR.ICTCLAS是中文分词界元老级工具了,作者开放出了free版本的源代码(1.0整理版本在此). 作者在 ...
- 从.NET和Java之争谈IT这个行业
一.有些事情难以回头 开篇我得表名自己的立场:.NET JAVA同时使用者,但更加偏爱.NET.原因很简单 1.NET语言更具开放性,从开源协议和规范可以看出; 2.语言更具优势严谨; 3.开发工具V ...
- 未能加载文件或程序集“Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5”或它的某一个依赖项。系统找不到指定的文件。
在创建ASP.NET MVC项目过程中发生了这个异常 未能加载文件或程序集"Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0 ...
- Aspose.Cells导出Excel(1)
利用Aspose.Cells导出excel 注意的问题 1.DataTable的处理 2.进行编码,便于中文名文件下载 3.别忘了Aspose.Cells.dll(可以自己在网上搜索) public ...
- vs2015 已经支持开发asp .net core 1.0 rc2 程序了
vs2015 已经支持开发asp .net core 1.0 rc2 程序了 http://mp.weixin.qq.com/s?__biz=MzI0MzM1ODczOQ==&mid=2247 ...
- 阅读微信支付demo收获
1,公司现有系统有很多,存放重要接口的日志分布在不同的库,每个系统都有单独的日志采集表,日志采集模块: ???? 这些日志可以统一放到一个地方,通过一个组件提供出去 ...
- Java Servlet+Objective-c图上传 步骤详细
一. Servlet 1.创建图片保存的路径 在项目的WebContent下创建一个上传图片的专属文件夹. 这个文件夹创建后,我们保存的图片就在该文件夹的真实路径下,但是在项目中是无法看到上传的图片的 ...
- java web学习总结(二十四) -------------------Servlet文件上传和下载的实现
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...