统计的力量——线段树详细教程

合集下载

线段树实现及应用分析

线段树实现及应用分析
// 因为是根据中序遍历建树,所以根结点的下一个是它的左儿子
BuildTree(l, (l + r) Div 2); Tree[temp].right := num + 1;
// 根据中序遍历,左子树的最后一个的下一个就是右儿子
BuildTree((l + r) Div 2 + 1, r);
// Tree[num]的一些参量可能需要根据已知条件的数列求得(实际上我们是根据它的左右儿子求得的, 因为它的左右儿子已经建完了,和原数列中的对应两段是等效的了)
5-5
6-7
8-8
9-9
10-10
1-1
2-2
6-6
7-7
在这次操作中,绿色和红色为遍历到的点。 [6,8]把它的标记下放给了[6, 7] (因为[8,8]是叶结点) ,把第一次修改的信息下放给了[6,7]和[8,8] , 这样就实现了原则二。然后, [8,8] [9,10]这两个点的参量被修改了。 橙色和红色的表示有懒标记的点。橙色的点记录了第一次修改的修改信息,
// 体现原则 1
// 运行到这里可以保证 Tree[v] 的左右儿子的参量都是准确的,这里需要根据左右儿子的参量修改 Tree[v]的参量
End;
3.查询区间[x,y] 查询区间[x,y]同样运用深搜,所遍历的 Tree 数组元素和修改区间[x,y] 是一样的。详见“2.修改区间[x,y] ”中的第一幅图。 由于查询操作比较简单,这里直接给出程序结构: Procedure Search(v: Longint); Var mid: Longint;
南开中学 张云昊
线 一、线段树用途及理解 1.线段树用途
树实现及应用分析
线段树是一种高级数据结构,用来维护一个数列,支持在 log 级别的时间内进 行区间修改和区间查询操作。 2.线段树理解 如果我们需要对元素个数为 1000 的一个数列进行区间操作,那么我们开一个长 度为 1000 的数组 A,每次对[x,y]进行操作时,就依次对 A[x]… A[y]进 行操作即可。 但是如果进行的操作次数很多,这样做很废时间。且显然,1000 的空间对于计 算机来说不算大,所以我们可以用一些空间换取时间。 我们可以让 A[1001]表示 A[1]和 A[2]的和状态,A[1002]表示 A[3] 和 A[4]的和状态…A[1500]表示 A[999]和 A[1000]的和状态。 这样,如果我需要对[341,557]进行查询,我只需要对 A[1171]A[1172]… A[1278]和 A[557]这 109 个元素进行查询就可以了。 可见, 虽然我们需要进行 500 次的预处理, 根据 A [1..1000] 求出 A [1001…1500] 但是,我们查询一个区间的速度提高了 2 倍! 同理,如果我们令 A[1501]表示 A[1]A[2]A[3]A[4]的和状态,以此类 推至 A[1750] ,对于区间[341,557] ,我们就只需要对 A[1586]A[1587]… A[1639]和 A[557]这 55 个元素进行查询即可,速度提高了 4 倍! 以此类推,我们就可以大大优化速度。 但是这就出现了一个问题,刚才提高速度的方法仅限于查询操作,如果用同样 方法进行修改操作的话,我们需要多修改很多元素,可能综合速度不但没提高反 而降低了。这个问题我们后面再进行解决,但是它给了我们一个启事:用单纯链 状的数据结构,还是无法完成任务的。 所以, 我们想到把 A [1001..1500] 摞到 A [1..1000] 上面, 再把 A [1501..1750] 摞到 A[1001..1500]上面,以此类推,这样我们就得到了一棵二叉树。这就是线段 树的雏形。 二、线段树操作分析 1.建树 我们用数组 Tree 存储这棵树,如果数列有 n 个元素,那么 Tree 有 2*n-1 个

统计的力量-线段树

统计的力量-线段树

清华大学 张昆玮
6
2019年10月17日
*计算几何在长期的发展中,
诞生了许多实用的数据结构。
*区间查询,穿刺查询都是计算几何解决的问题 *作为特例中的特例,线段树解决的问题是:
* 一维空间上的几何统计
*高维推广(kd-tree & …)可以进行正交查询
*由于竞赛中涉及计算几何的内容有限,不展开
*计算几何!
2019年10月17日
*for(T[n+=M]=V, n>>=1;n;n>>=1)
* T[n]=T[n+n]+T[n+n+1];
*没了? *没了。
清华大学 张昆玮
*C语言更简单
35
2019年10月17日
*仅使用了两倍原数组的空间 *其中还完整地包括了原数组 *构造容易:
* For i=M-1 downto 1 do T[i]=T[2i]+T[2i+1];
44
2019年10月17日
*标记的传递与收集
懒惰即美德。
清华大学 张昆玮
45
2019年10月17日
清华大学 张昆玮
*区间修改
噩梦的开始
46
2019年10月17日
*RMQ (Range Minimum Query) *区间最小值查询 *线段树 *支持区间修改:
* 某一区间的数值全部增加一个可正可负的数
2019年10月17日
*这不就和树状数组一样了? *本来就应该一样。
*回过头说,树状数组究竟是什么? *就是省掉一半空间后的线段树加上中序遍历 *计算位置需要lowbit什么的 *我们用的是先序遍历,符合人的思考习惯。

线段数讲义

线段数讲义

线段树入门(一)路桥中学陈朝晖今天,我们来介绍一种非常特殊的数据结构——线段树。

首先,来看这个问题:给你n个数,仅有两种操作:(1)给第i个数的值添加x(2)询问区间[a,b]的总和是多少CODEVS 1080 线段树练习时间限制: 1s 空间限制: 128000 KB 题目等级 : 钻石 Diamond题目描述 Description一行N个方格,开始每个格子里都有一个整数。

现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。

现在要求你能对每个提问作出正确的回答。

1≤N<100000,,提问和修改的总数m<10000条。

输入描述 Input Description输入文件第一行为一个整数N,接下来是1行共n个整数,表示格子中原来的整数。

下面是一个正整数m,接下来有m行,表示m个询问,第一个整数表示询问代号,询问代号1表示增加,后面的两个数x和A表示给位置X上的数值增加A,询问代号2表示区间求和,后面两个整数表示a和b,表示要求[a,b]之间的区间和。

输出描述 Output Description共m行,每个整数样例输入 Sample Input645621341 3 52 1 41 1 92 2 6样例输出 Sample Output2222数据范围及提示 Data Size & Hint1≤N≤100000, m≤10000 。

从题目中所给的数据来看,数据量非常大,所需要的查询次数同样非常多。

#include <iostream>usingnamespace std;int dat[Maxn],N,M;struct Tree{int left,right;longlong sum;}tr[Maxn<<2];//tr[i]表示第i线段树,其中[left,right]表示数据区域的边界,sum表示线段树中当前这一段的总和//数组中的每一个结点都将最终设置在线段树的叶子节点位置上,//而线段树中还存在内部结点的存储。

幼儿园大班综合《树木统计》教案

幼儿园大班综合《树木统计》教案

一、教学目标1. 了解树木统计的基本概念,知道统计是一种收集、整理、描述数据的方法。

2. 学会使用简单的工具(如计数器、画图工具等)进行树木统计。

3. 培养幼儿的观察能力、动手操作能力和团队协作能力。

4. 培养幼儿对自然环境的热爱和保护意识。

二、教学内容1. 树木统计的概念和作用2. 统计方法的学习和实践3. 树木统计结果的展示和分析4. 保护树木的重要性三、教学准备1. 教学PPT或者教学图片2. 计数器、画图工具等统计工具3. 树木统计表格4. 保护树木的宣传资料四、教学步骤1. 引入:通过图片或者实物展示,引导幼儿观察树木,并提出问题:“你们知道我们身边的树木有多少吗?我们可以用什么方法来了解呢?”2. 讲解:介绍树木统计的概念和作用,讲解统计方法,并示范操作。

3. 实践:分组进行树木统计实践,幼儿使用计数器、画图工具等统计工具进行统计。

4. 展示:每组展示统计结果,并分享统计过程中的趣事。

5. 总结:讲解保护树木的重要性,引导幼儿养成保护树木的良好习惯。

五、教学评价1. 观察幼儿在实践过程中的动手操作能力和团队协作能力。

2. 评估幼儿对树木统计概念的理解和运用能力。

3. 搜集幼儿在实践过程中的作品,分析幼儿的创造力和想象力。

4. 调查幼儿对保护树木的认识和行为变化。

六、教学拓展1. 延伸统计概念:引导幼儿思考还可以统计哪些自然事物,如花朵、昆虫等。

2. 环保主题活动:组织幼儿进行植树造林活动,提高幼儿的环保意识。

3. 亲子活动:邀请家长参与,共同进行家庭树木统计,增进亲子关系。

七、教学资源1. 网络资源:查找相关统计方法和保护树木的资料,以便进行教学分享。

2. 图书资源:搜集关于统计和环保的幼儿图书,丰富幼儿的知识。

3. 实物资源:准备各种统计工具和材料,确保教学实践的顺利进行。

八、教学评价1. 观察幼儿在实践过程中的动手操作能力和团队协作能力。

2. 评估幼儿对树木统计概念的理解和运用能力。

树状数组线段树简单介绍

树状数组线段树简单介绍


线段存数!
线段树的基本操作
建树:

1、由于线段树的特殊性,可以使用类似完全二 叉树的结构来建立,但是线段树不是完全二叉 树,开4倍的空间才可以保证结构正确性! 2、可以使用动态申请空间方法new,delete 3、与开一个数组空间,利用游标控制建立线段 树,同时记录左右儿子的下标。
线段树的基本操作
二维树状数组的简单介绍
对于一个二维数组a[][]以及其对应的二维c[][] {1,1,1,1} {1,2,1,4} {1,1,1,1} {2,4,2,8} {1,1,1,1} {1,2,1,4} {1,1,1,1} {4,8,4,16} 思想很简单,具体操作我的blog上有,有时间大 家可以去看看。
[0,8] [0,4] [0,2]
[6,8]
[4,8] [2,4] [4,6] [6,8]
[4,8] [0,8] [0,4]
[0,2] [2,4]
[4,6]
二维线段树的结构介绍

二维线段树的第二种形式:
(4,3)
(1,1)
(2,3) (1,2) (2,2)
(4,3) (1,1)
(2,2)
(4,2)
线段树的基本操作
计算连续段数

连续线段数line指的是区间中互不相交的线段条数。


连续线段数并不能像测度那样将两个子结点中的连续线段数简单 相加。于是我们引进了两个量lbd,rbd,分别表示区间的左右两 端是否被线段覆盖。 1 (左端点被线段覆盖到) lbd = 0 (左端点不被线段覆盖到) 1 (右端点被线段覆盖到) rbd = 0 (右端点不被线段覆盖到)
线段树例题分析
例5(poj 3277 City Horizon) 题目描述:已知N座建筑,每座建筑对于一个三 元组(Ai,Bi,Hi)表示从Ai到Bi高为Hi的建筑, 求从侧面看可看到的总面积。 Sample input Sample output

统计的力量——线段树详细教程共103页文档

统计的力量——线段树详细教程共103页文档

统计的力量——线段树详细教程
1、合法而稳定的权力在使用得当时很 少遇到 抵抗。 ——塞 ·约翰 逊 2、权力会使人渐渐失去温厚善良的美 德。— —伯克
3、最大限度地行使权力总是令人反感 ;权力 不易确 定之处 始终存 在着危 险。— —塞·约翰逊 4、权力会奴化一切。——塔西佗
5、虽然权力是一头固执的熊,可是来自 子可以 拉着它 的鼻子 走。— —莎士 比
46、我们若已接受最坏的,就再没有什么损失。——卡耐基 47、书到用时方恨少、事非经过不知难。——陆游 48、书籍把我们引入最美好的社会,使我们认识各个时代的伟大智者。——史美尔斯 49、熟读唐诗三百首,不会作诗也会吟。——孙洙 50、谁和我一样用功,谁就会和我一样成功。——莫扎特

线段树_树状数组I(11页建树有修正)

线段树_树状数组I(11页建树有修正)

如果原数组从a[1]~a[n],调用build(1,1,n)即可
12
• 更新某个点的数值,并维护相关点的信息
线段树——代码实现(更新)
void update(int id,int pos,int val) { if (tree[id].left==tree[id].right) { tree[id].sum=tree[id].max=val; } else { int mid=(tree[id].left+tree[id].right)/2; if (pos<=mid) update(id*2,pos,val); else update(id*2+1,pos,val); tree[id].sum=tree[id*2].sum+tree[id*2+1].sum; tree[id].max=max(tree[id*2].max,tree[id*2+1].max) } }
5
线段树——结构
• 线段树的本质是一棵二叉树,丌同亍其它二叉树, 线段树的每一个节点记录的是一段区间的信息。 • e.g. 对亍长度为5的数组a[1]~a[5]
[1,5] [1,3] [4,5] 对于任一非叶子节点, 若该区间为[L,R],则 左儿子为[L,(L+R)/2] 右儿子为[(L+R)/2+1,R]
23
树状数组——总结
1、树状数组可以更新点查询区间,也可以更新区间 查询点,但一般不能更新区间查询区间。 2、单操作时间复杂度O(log2N),空间复杂度O(N). 3、代码简洁。 思考:1、如何实现树状数组更新区间查询点?(例如 给某个区间统一加一个数,询问某点当前值) 2、修改tree数组的定义,使其能够实现更新 某个点的值,并询问[1,pos]中的最大值。

线段树讲解——精选推荐

线段树讲解——精选推荐

线段树讲解浅谈线段树在信息学竞赛中的应⽤岳云涛yyt @ comindeWuhan University【摘要】本⽂介绍了⼀种⾼效的基于分治思想的数据结构——线段树,具体讲解了线段树的建树,查找,删除,统计等基本操作。

并结合了⼀些例题深⼊研究了线段树的基本性质和线段树的应⽤⽅法。

⽂章最后给出了⼀些线段树的练习题⽬。

【关键词】数据结构⼆叉树线段树【⽬录】引⾔ (3)1 线段树 (3)1.1 线段树的基本结构 (3)1.2 线段树的性质 (4)1.3 线段树的基本存储结构和操作 (4)2 线段树的初级应⽤ (9)2.1 例题:City Horizon (9)2.2 例题 Joseph Problem (12)3 线段树的进阶应⽤ (15)3.1 例题 Frequent Values (15)3.2 例题 K-th Number (17)4 线段树的⼀些推⼴应⽤ (17)4.1 多维线段树 (17)4.2 线段树与其他数据结构的组合 (18)5 线段树应⽤总结 (19)6 线段树练习题⽬推荐 (19)【正⽂】引⾔在信息学竞赛中,我们经常会碰到⼀些跟区间有关的问题,⽐如给⼀些区间线段求并区间的长度,或者并区间的个数等等。

这些问题的描述都⾮常简单,但是通常情况下数据范围会⾮常⼤,⽽朴素⽅法的时间复杂度过⾼,导致不能在规定时间内得到问题的解。

这时,我们需要⼀种⾼效的数据结构来处理这样的问题,在本⽂中,我们介绍⼀种基于分治思想的数据结构--线段树。

1 线段树1.1 线段树的基本结构线段树是⼀种⼆叉树形结构,属于平衡树的⼀种。

它将线段区间组织成树形的结构,并⽤每个节点来表⽰⼀条线段。

⼀棵[1,10)的线段树的结构如图 1.1所⽰:图1.1 线段树的结构可以看到,线段树的每个节点表⽰了⼀条前闭后开,即[a,b)的线段,这样表⽰的好处在于,有时候处理的区间并不是连续区间,可能是离散的点,如数组等。

这样就可以⽤[a,a+1)的节点来表⽰⼀个数组的元素,做到连续与离散的统⼀。

线段树111 ppt课件

线段树111 ppt课件
}
• 这样,修改和询问都可以在O(lgN)时间内解决。 • 最后问题:如何表示线段树,如何建立线段树,
如何初始化线段树。 • 表示:
struct node { int sum, lbound, rbound; node *lchild, *rchild;
}; node pool[N*3], *alloc = pool, *root;
线段树
• 维护伪代码,将Ki修改为X,相当于将[i,i]修改为X
• void Modify( T ) { if ( T左边界 == T右边界 ) { T中元素和 = X //因为T中仅有一个元素 } else { mid = ( T左边界 + T右边界 ) / 2 value = 0 if ( i <= mid ) { value += Modify( T左子结点 ) } if ( i > mid ) { value += Modify( T右子结点 ) } T中元素和 = value }
提示:利用 Si = Si-1 + Ki
区间统计
• 现在增加一些难度: 在m个询问中穿插t个修改,每个修改要 求将某个Ki修改成指定值
• 如果还是用预处理S的方法,那么每次 修改时维护S数组的代价是多少?O(n) 的(你能说出理由吗?)
• 这样t次修改复杂度是O( tn )的,有没有 更好的方法解决这个问题?
线段树111 ppt课件
本讲稿主要来源
南开大学、浙江大学、福建大学
线段树
• 在一类问题中,我们需要经常处理可以 映射在一个坐标轴上的一些固定线段, 例如说映射在OX轴上的线段。由于线段 是可以互相覆盖的,有时需要动态地取 线段的并,例如取得并区间的总长度, 或者并区间的个数等等。一个线段是对 应于一个区间的,因此线段树也可以叫 做区间树。

简单线段树知识点详解

简单线段树知识点详解

简单线段树知识点详解简单线段树知识点详解本篇随笔讲解信息学奥林匹克竞赛中强⼤且常⽤的猛⼠数据结构——线段树。

因为线段树博⼤精深,有许多变形和应⽤⽅式。

区区⼀篇随笔是绝对⽆法尽叙的。

所以在这⾥笔者只为读者讲解简单线段树。

希望每⼀位有缘读到这篇随笔的⼈都能对线段树有⼀个深刻的理解,并会解决线段树的简单问题。

由于线段树属于⼀种⾼级数据结构。

所以在学习线段树的时候需要的知识铺垫⽐较多。

建议读者先对树状结构、⼆分以及递归编程法有深刻的认识和理解,然后再进⾏线段树的学习。

这样的话会⽅便很多。

当然,如果你缺少了前述铺垫知识的⼀项或⼏项,也并不代表你⼀定学不好线段树。

勇于尝试、敢于挑战、努⼒思考。

这会对你线段树及以后很多知识点的学习有极⼤的促进作⽤。

那我就开始了。

线段树的概念在介绍线段树的概念之前,我先介绍线段树的⽤途:线段树⼀般⽤于区间统计。

即统计[x,y]区间内的某⼀个特性。

这个特性可以有很多,⽐如区间求和,区间最值等等。

定义什么的特别复杂,我们争取⽤⼀张图搞清楚对线段树的直观理解。

上图是⼀棵1-5区间的线段树。

我们发现这个线段树是⼀棵⼆叉树,每个节点表⽰⼀个区间,根节点对应区间1-n.每个叶⼦节点都只表⽰单点,针对⼆叉树编号的性质(⼆叉树的每个⽗亲节点f的左节点编号是2f,右节点编号是2f+1),我们可以使⽤⼀维数组实现线段树。

也就是说,我们开⼀个⼀维数组,⼀维数组的下标表⽰这棵线段树的节点编号,⾥⾯存的值表⽰这个节点所表⽰的区间中我们要维护的特性:如和、最值等。

简单线段树⽀持的操作刚刚已经说过,线段树是⼀种博⼤精深的数据结构,它的功能和操作实在是太多了。

之所以反复强调这些,是为了让读者清楚,在线段树的海洋中,我们都不过是探其⼀⾓罢了,千万不要妄⾃尊⼤,以为⾃⼰已经把线段树全部搞完了。

简单线段树⽀持单点查询,区间查询,单点修改,区间修改,我们发现这和树状数组的⼀些⽀持项⽬类似,但是却不完全包含,因为树状数组仅⽀持区间求和,且必须是1−n的求和,如果想要[x,y]的任意区间求和的话,必须需要使⽤差分思想来相减。

线段树总结——精选推荐

线段树总结——精选推荐

线段树总结之前做了些线段树相关的题⽬,开学⼀段时间后,想着把它整理下,完成了⼤⽜NotOnlySuccess的博⽂“完全版线段树”⾥的⼤部分题⽬,其博⽂地址,然后也加⼊了⾃⼰做过的⼀些题⽬。

整理时,更新了之前的代码风格,不过旧的代码仍然保留着。

同样分成四类,不好归到前四类的都分到了其他。

树状数组能做,线段树都能做(如果是内存限制例外),所以也有些树状数组的题⽬,会标⽰出来,并且放到其他类⾥。

⼀、单点更新1.:有N个兵营,每个兵营都给出了⼈数ai(下标从1开始),有四种命令,(1)”Addij",表⽰第i个营地增加j⼈。

(2)“Sub i j”,表⽰第i个营地减少j⼈。

(3)“Query ij",查询第i个营地到第j个营地的总⼈数。

(4)”End“,表⽰命令结束。

解题报告。

2.:给你N个数,M个操作,操作分两类。

(1)"QAB“,查询区间[A,B]内的最⼤值。

(2)"UAB",将第A个数的值改成B。

解题报告。

3.:给你N个数,要求统计它的所有形式的逆序对的最⼩值。

它的所有形式的意思是,不断将数组开头的第⼀个数放到数组的最后⾯。

解题报告。

4.:有⼀块板,规格为h*w,然后有n张海报,每张海报的规格为1*wi,选择贴海报的位置是:尽量⾼,同⼀⾼度,选择尽量靠左的地⽅。

要求输出每张海报的⾼度位置。

解题报告。

5.:有N个⼈排队,每⼀个⼈都有⼀个val来对应,每⼀个后来⼈都会插⼊当前队伍的某⼀个位置pos。

要求把队伍最后的状态输出。

解题报告。

6.: N个⼩孩围成⼀圈,他们被顺时针编号为 1 到 N。

每个⼩孩⼿中有⼀个卡⽚,上⾯有⼀个⾮ 0 的数字,游戏从第 K 个⼩孩开始,他告诉其他⼩孩他卡⽚上的数字并离开这个圈,他卡⽚上的数字 A 表明了下⼀个离开的⼩孩,如果 A 是⼤于 0 的,则下个离开的是左⼿边第 A 个,如果是⼩于 0 的,则是右⼿边的第 A 个⼩孩。

线段树详解与实现

线段树详解与实现

线段树详解与实现此篇⽂章⽤于记录《玩转数据结构》课程的学习笔记什么是线段树线段树也被称为区间树,英⽂名为Segment Tree或者Interval tree,是⼀种⾼级的数据结构。

这种数据结构更多出现在竞赛中,在常见的本科数据结构教材⾥没有介绍这种数据结构。

但是,在⾯试中却有可能碰到和线段树相关的问题。

那么为什么会产⽣线段树这种数据结构,线段树到底是为了解决什么样的⼀种问题呢?其实这⾥的线段可以理解为区间,线段树就是为了解决区间问题的。

有⼀个很经典的线段树问题是:区间染⾊。

假设有⼀⾯墙,长度为 n,每次选择⼀段墙进⾏染⾊。

在区间染⾊的过程中,每次选择⼀段区间进⾏染⾊,这时新的颜⾊可能会覆盖之前的颜⾊。

最后的问题是:在经过 m 次染⾊操作后,我们可以在整个区间看见多少种颜⾊?更加普遍的说法是:在经过 m 次染⾊操作后,我们可以在区间[i, j]内看见多少种颜⾊?由于第⼀个问题是第⼆个问题的⼀个特例,我们采⽤第⼆种问题来思考解决⽅法。

从上⾯可以看出,我们对于区间,有 2 种操作,分别是染⾊操作和查询区间的颜⾊,使⽤更加⼀般的说法,染⾊操作就是更新区间,查询区间的颜⾊就是查询区间。

这类问题⾥⾯,更加常见的的是区间查询:⼀个数组存放的不再是颜⾊,⽽是具体的数字,查询某个区间[i, j]的统计值。

这⾥的统计值是指:区间内最⼤值、最⼩值、或者这个区间的数字和。

⽐如:查询 2018 年注册的⽤户中消费最⾼的⽤户查询 2018 年注册的⽤户中消费最低的⽤户注意上⾯两种情况都是动态查询,我们查询的消费数据不只是 2018 的消费数据。

如果我们想查询 2018 年中消费最⾼的⽤户,那么 2018 年的数据已经固定了,我们直接在这⼀年的数据中进⾏统计分析就⾏了。

但是⼀个 2018 年注册的⽤户,在 2019 年、2020 年都可能会有消费。

我们实际上查询的是:2018 年注册的⽤户中,到现在为⽌,消费最⾼的⽤户。

这种情况下,数据是在动态变化的,也就是说:2017 年注册的⽤户中,每个⽤户的消费额是会更新的,这就对应到更新区间的操作。

《线段树应用》PPT课件

《线段树应用》PPT课件
考虑第i个点qxyz增加对数组的限制maxj建立关于数组max的线段树每增加一个节点的限制就相当于修改线段树中的一个区间内的值要修改的子树收缩成一个叶子节点一个叶子节点释放出两个儿子修改的区间如果包含节点修改的区间如果包含节点vv表示的区间那么表示的区间那么vv及及vv的儿子的儿子都要修改但是我们只要修改都要修改但是我们只要修改vv
要删除的子树
收缩成一个 叶子节点
一个叶子节点
释放出两个儿子
精选ppt
25
优化后每次删除、统计、插入的复杂度都 是O(n*logv),所以总的复杂度降为 O(m*n*logv);
精选ppt
26
【问题分析 】
由于这是个二维的区间,不妨将整个二 维的区间建成类似线段树的面积树:
假设整个二维区间是[1..2k][1..2k],递归 定义一棵树T: 1 T的根节点为整个二维区间。
P4
P8
P7
X
精选ppt
6
将所有点排序后发现,在同一水平线的点中,设 为P1,P2,P3,P4……Pn,P1必须连它右边的 点——P2,P3只能连P4,P5连P6……,同垂直线 上的点也是如此。
如果有解,解是唯一的,那么最小长度的问题就 解决了。
精选ppt
7
【问题分析】
不相连—不合法
自交—不合法
在一个三维正坐标系中,存在N(N<=5000) 个点,现在要求一点P(x,y,z),使得O(0, 0,0)与P(x,y,z)两个顶点构成的长方体 内不包括N个点中的任何一个点(在长方体 边缘不算包括),并使这个长方体的体积最 大。x,y,z均不得超过1000000。
精选ppt
14
【问题分析】
P(x,y,z)代表的长方体包含一点Q,那么P的 所有坐标值,都大于Q点的坐标值。

最新二分法与统计问题(线段树)

最新二分法与统计问题(线段树)

二分法与统计问题(线段树)二分法与统计问题 (线段树)OICF-信息学奥林匹克综合论坛[关键字]线段树二叉树二分法[摘要]我们经常遇到统计的问题。

这些问题的特点是,问题表现得比较简单,一般是对一定范围内的数据进行处理,用基本的方法就可以实现,但是实际处理的规模却比较大,粗劣的算法只能导致低效。

为了解决这种困难,在统计中需要借助一些特殊的工具,如比较有效的数据结构来帮助解决。

本文主要介绍的是分治的思想结合一定的数据结构,使得统计的过程存在一定的模式,以到达提高效率的目的。

首先简要介绍线段树的基础,它是一种很适合计算几何的数据结构,同时也可以扩充到其他方面。

然后将介绍 IOI2001 中涉及的一种特殊的统计方法。

接着将会介绍一种与线段树有所不同的构造模式,它的形式是二叉排序树,将会发现这种方法是十分灵活的,进一步,我们将略去对它的构造,在有序表中进行虚实现。

目录一线段树1.1 线段树的构造思想1.2 线段树处理数据的基本方法1.3 应用的优势1.4 转化为对点的操作二一种解决动态统计的静态方法2.1 问题的提出2.2 数据结构的构造和设想2.3 此种数据结构的维护2.4 应用的分析三在二叉排序树上实现统计3.1 构造可用于统计的静态二叉排序树3.2 进行统计的方法分析3.3 一个较复杂的例子四虚二叉树4.1 虚二叉树实现的形态4.2 一个具体的例子4.3 最长单调序列的动态规划优化问题[正文]一线段树在一类问题中,我们需要经常处理可以映射在一个坐标轴上的一些固定线段,例如说映射在 OX 轴上的线段。

由于线段是可以互相覆盖的,有时需要动态地取线段的并,例如取得并区间的总长度,或者并区间的个数等等。

一个线段是对应于一个区间的,因此线段树也可以叫做区间树。

1.1线段树的构造思想线段树处理的是一定的固定线段,或者说这些线段是可以对应于有限个固定端点的。

处理问题的时候,首先抽象出区间的端点,例如说 N 个端点 ti (1 ≤ i ≤ N) 。

【zkw线段树讲稿】统计的力量-线段树

【zkw线段树讲稿】统计的力量-线段树
存放在树的根部,所以下传标记做什么?
*
清华大学 张昆玮
49
2013年1月8日
*
庄周梦蝶而已
清华大学 张昆玮
50
2013年1月8日
* 一根线段,支持区间染色。
询问区间是否同色?
* 区间染色需要使用染色标记 * 询问的时候就直接看标记嘛
1表示红色,2表示蓝色,3绿色,0杂色
*
清华大学 张昆玮
51
2013年1月8日
* 区间查询,穿刺查询都是计算几何解决的问题 * 作为特例中的特例,线段树解决的问题是:
* 一维空间上的几何统计
* 高维推广(kd-tree
& …)可以进行正交查询
* 由于竞赛中涉及计算几何的内容有限,不展开
*
清华大学 张昆玮
7
2013年1月8日
* 线段树把数轴分成区间来处理 * 如[8,10), [10,11), … * 实际上我们面对的往往是离散量 * 竞赛中出现的线段树往往因此退化为“点树” * 即,最底层的线段只包含一个点: * 如:[8,9)中只有整点8而已 * 在之后的讨论中,我们不再区别“点树”与线段
* Get 1
* Get [2,4) in [2,4)
* 虽然每次都有可能同时递归进入两棵子树,
但每层实际上只访问了两个节点。为什么?
* 因为查询是连续的啊……
*
清华大学 张昆玮
11
2013年1月8日
如果同一层有三个被访问,依次为A,B,C 查询是连续的,有了A和C,就一定包括B在树中的兄弟 那我直接用B的父亲来计算好了,为什么要用B?
*
清华大学 张昆玮
38
2013年1月8日
(…,5)?

线段树_刘汝佳(有版权)

线段树_刘汝佳(有版权)

SUM的计算
• 右图表示影响 SUM(7, 9)的所 有区间
– 影响全部: [1,9], [5,9], [7,9] – 影响部分: 7, [8,9], 8, 9
[1,2] 1 2 [1,9] [1,4] [3,4] 3 4 [5,9] [5,6] 5 6 [7,9] 7 [8,9] 8 9
完整的算法
– 得到讨论区间(可能要先离散化) – 设计区间附加信息和维护/统计算法
• 线段树自身没有任何数据, 不像BST一样有 一个序关系 • 警告 想清楚 警告: 想清楚附加信息的准确含义 不能有 准确含义, 准确含义 半点含糊! • 建议 先设计便于解题 建议: 便于解题的附加信息,如果难 便于解题 以维护就加以修改
[3,4]
5 3 3 5 5 1 1
[4,5]
5 3 3 5
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4 5
1 2 2 3 3 4 4
1 2 2 3 3 4 4 5
矩形树
• 每个矩形分成四份
– 空间复杂度:XY – 时间复杂度:X+Y
(x2,y2) (1,1)
(4,3)
Son1
Son2
– ADD: 给i对应结点的所有直系祖先s值增加k – SUM: 做区间分解, 把对应结点的s值相加
动态统计问题II
• 包含n个元素的数组A
– ADD(i, j, k): 给A[i], A[i+1], … A[j]均增加k – QUERY(i): 求A[i]
• 先看看是否可以沿用刚才的附加信息
– QUERY(i)就是读取i对应的结点上的s值 – ADD呢? 极端情况下, 如果是修改整个区间, 则 所有结点都需要修改!
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

2013年7月25日
* 我们可以直接找到一个数对应的叶子 * 不用自顶向下慢慢地找啊找 * “直接加 4 ”多简单! * …… * 直接找到叶子? * 无限遐想中……
*
清华大学 张昆玮
25
2013年7月25日
*
可以直接找到叶子?
清华大学 张昆玮
26
2013年7月25日
(0,5)?
1
2 4 8 9 10 5 11 12 6 13 14 3 7 15
清华大学 张昆玮
41
2013年7月25日
树状 数组
线段 树
*
清华大学 张昆玮
42
2013年7月25日
* 我之前用这种写法做过不少题…… * 大家都说我的代码看不懂 * 我说这就是一个树状数组 * 写树状数组的人说没有lowbit * 我说那就算是线段树吧 * 大家不相信非递归的线段树这么短…… * 我:……
清华大学 张昆玮
13
2013年7月25日
* 原因是区间和的性质非常好 * 满足区间减法 * 区间减法什么的最讨厌了!后面再说! * 不过直接前缀和不是万能的! * 如果修改元素的话……
*
清华大学 张昆玮
14
2013年7月25日
数据结构 直接存储原数组 直接存储前缀和 线段树
修改元素 O(1) O(n) O(logn)

*
7
2013年7月25日
清华大学 张昆玮
*
如果我给MM的第一印象不到80分的话……
是不是老老实实地早点罢手比较好?
清华大学 张昆玮
8
2013年7月25日
[0,4) [0,2) 0 1 2 [2,4)
[1,4) ?
3
*
清华大学 张昆玮
9
2013年7月25日
* [1,4) in [0,4)
* 左边,[1,2) in [0,2)
*
清华大学 张昆玮
35
2013年7月25日
* 因为树状数组依赖于区间减法 * 区间减法什么的,最讨厌了……后面再讲,再讲 * 反正如果只问问前缀和,不问区间和的话 * 那我也可以只用一倍空间!
*
清华大学 张昆玮36Fra bibliotek2013年7月25日
(…,5)?
1
2 4 8 9 10 5 11 12 6 13 14 3 7 15
* Func Change(n,NewValue)
* n += M; * Tree[n] = NewValue; * While n > 1 do
* n = n >> 1; * Tree[n] = Tree[2n] + Tree[2n+1];
*
清华大学 张昆玮
33
2013年7月25日
* for(T[n+=M]=V, n>>=1;n;n>>=1)
*
清华大学 张昆玮
* 根据 D. E. Knuth 的分类方法
计算机算法可以分为两类:
* 数值算法与非数值算法 * 其中的非数值算法包括:
* 索引 * 分类 * 统计 * ……
*
清华大学 张昆玮
2
2013年7月25日
* POJ上的某题,时限很紧…… * 大家都用树状数组,但是有人只会用线段树呢? * 而且我可以轻易改出一道不能用树状数组的题 * 在线段树一次次TLE后,有一个ID发帖抱怨 * “下次写一个汇编版非递归线段树,再超时?” * 可是大家都知道,超时的代码已经2k了。 * 其实我写的就是线段树。很快,而且不到1k。
*
清华大学 张昆玮
37
2013年7月25日
(…,5)?
1
2 4 8 9 10 5 11 12 6 13 14 3 7 15
*
清华大学 张昆玮
38
2013年7月25日
(…,5)?
1
2 4 8 9 10 5 11 12 6 13 14 3 7 15
*
清华大学 张昆玮
39
2013年7月25日
1-No
*
清华大学 张昆玮
20
2013年7月25日
1 2 4 5 6 3 7
*
清华大学 张昆玮
21
2013年7月25日
* N 的左儿子是 2N * N 的右儿子是 2N + 1 * N 的父亲是 N >> 1 * …… * 不就是个堆存储么?不用讲了吧?
*
清华大学 张昆玮
22
2013年7月25日
1 10 100 101 110 11 111
* 遗憾的是,这种朴素的方法并不是那么容易实现 * 而且存在严重的效率问题(常数太大)
*
清华大学 张昆玮
17
2013年7月25日
*
清华大学 张昆玮
18
2013年7月25日
*
工欲善其事,必先利其器。
清华大学 张昆玮
19
2013年7月25日
* 虽然可以设计出三叉,四叉,……线段树 * 但是我们先从二叉树开始 * 登高必自迩,行远必自卑 * 多叉怎么办后面再讲(这还要讲?自己研究去) * 为了不处理各种特殊情况,假设二叉树是满的! * 不是满的?你的总区间是[0,1000)? * 你就当作[0,1024)不就好了?
A
B
C
*
清华大学 张昆玮
11
2013年7月25日
*
功利点说,没啥用的东西咱不学……
清华大学 张昆玮
12
2013年7月25日
*
区区区间和,用的着线段树?
* 直接把原数组处理成前缀和 * For i=2 to n do
* A[i] += A[i-1]
* Ans(a,b) = A[a] - A[b-1]
*
清华大学 张昆玮
3
2013年7月25日
* 运行速度快 * 适应能力强 * 编写方便 * 结构简单 * 容易调试 * 关键在于灵活实现
*
清华大学 张昆玮
4
2013年7月25日
*
为什么在《算法导论》和黑书中都难见到其踪迹?
清华大学 张昆玮
5
2013年7月25日
* 计算几何在长期的发展中,
诞生了许多实用的数据结构。
*
清华大学 张昆玮
23
2013年7月25日
* 字母树! * 存放的是100,101,110,111四个串! * 每个节点存的是以这个节点为前缀的所有节点和 * 例:1中存的是所有四个以1开头的和。 * 似乎从 100 到 111 就正好是原数组 * 貌似……下标减 4 就行了?
*
清华大学 张昆玮
24
2-1 3-No
4-2
5-No
6-3
7-No
*
清华大学 张昆玮
40
2013年7月25日
* 这不就和树状数组一样了? * 本来就应该一样。 * 回过头说,树状数组究竟是什么? * 就是省掉一半空间后的线段树加上中序遍历 * 计算位置需要lowbit什么的 * 我们用的是先序遍历,符合人的思考习惯。
*
* T[n]=T[n+n]+T[n+n+1];
* 没了? * 没了。
*
清华大学 张昆玮
34
2013年7月25日
* 仅使用了两倍原数组的空间 * 其中还完整地包括了原数组 * 构造容易:
* For i=M-1 downto 1 do T[i]=T[2i]+T[2i+1];
* 太好写了!好理解! * 自底向上,只访问一次,而且不一定访问到顶层 * 实践中非常快,与树状数组接近 * 为什么呢?后面再讲。
存放在树的根部,所以下传标记做什么?
*
清华大学 张昆玮
48
2013年7月25日
*
庄周梦蝶而已
清华大学 张昆玮
49
2013年7月25日
* 一根线段,支持区间染色。
询问区间是否同色?
* 区间染色需要使用染色标记 * 询问的时候就直接看标记嘛
1表示红色,2表示蓝色,3绿色,0杂色
*
清华大学 张昆玮
50
2013年7月25日
* 2为红色,3为蓝色,1为杂色
修改3为红色 查询1,杂色?
* 永久化的标记就是值啊!值是自动维护的啊! * 其实我们的修改算法在修改3的时候已经维护了1 * 自底向上顺便重算所有遇到的节点标记即可 * If (Mark[x]==0 and Mark[2x]==Mark[2x+1])
* If ((s and 1) == 0) Answer += Tree[s + 1]; * If ((t and 1) == 1) Answer += Tree[t – 1]; * s = s >> 1, t = t >> 1;
*
清华大学 张昆玮
29
2013年7月25日
* for (s=s+M-1,t=t+M+1;s^t^1;s>>=1,t>>=1) {
*
清华大学 张昆玮
43
2013年7月25日
*
懒惰即美德。
清华大学 张昆玮
44
2013年7月25日
*
噩梦的开始
清华大学 张昆玮
45
2013年7月25日
* RMQ (Range Minimum Query) * 区间最小值查询 * 线段树 * 支持区间修改:
* 某一区间的数值全部增加一个可正可负的数
*
清华大学 张昆玮
27
2013年7月25日
(0,5)?
相关文档
最新文档