线段树及其应用

合集下载

线段树及其应用场景

线段树及其应用场景

线段树及其应用场景一、引言线段树(Segment Tree)是一种基于树状数组(Binary Indexed Tree)的数据结构,用于高效地处理区间查询问题。

它在许多算法和数据结构问题中都有广泛应用,如区间最值查询、区间修改和区间统计等。

二、线段树的定义和构建线段树是一种二叉树结构,每个节点代表一个区间。

叶子节点表示原始数据的单个元素,而非叶子节点则表示区间的合并结果。

线段树的构建过程可以通过递归或迭代的方式完成。

3、线段树的应用场景3.1 区间最值查询线段树的一个常见应用是区间最值查询。

给定一个数组,我们希望能够快速找到指定区间内的最大或最小值。

线段树能够在O(log n)的时间复杂度内完成单次查询,并且支持O(log n)的时间复杂度的区间修改操作。

3.2 区间修改线段树还可以用于区间修改问题。

例如,给定一个数组,我们需要对指定区间内的元素进行加法或乘法操作。

线段树可以在O(log n)的时间复杂度内完成单次修改,并且支持O(log n)的时间复杂度的区间查询操作。

3.3 区间统计线段树还可以用于区间统计问题。

例如,给定一个数组,我们需要统计指定区间内满足某种条件的元素个数。

线段树可以在O(log n)的时间复杂度内完成单次统计,并且支持O(log n)的时间复杂度的区间修改操作。

4、线段树的实现和优化4.1 线段树的存储结构线段树可以使用数组或链表来实现。

数组实现简单高效,但需要额外的空间;链表实现节省空间,但查询和修改操作的时间复杂度会增加。

4.2 线段树的查询和修改算法线段树的查询和修改算法可以通过递归或迭代的方式来实现。

递归实现简洁直观,但可能会导致函数调用过多;迭代实现效率较高,但代码复杂度较高。

4.3 线段树的优化技巧线段树的性能可以通过一些优化技巧来提升。

例如,使用延迟标记(Lazy T ag)来延迟区间修改操作的执行,减少递归或迭代次数;使用预处理技巧来提前计算一些中间结果,减少查询或修改的时间复杂度。

『zkw线段树及其简单运用』

『zkw线段树及其简单运用』

『zkw 线段树及其简单运⽤』<更新提⽰><第⼀次更新>阅读本⽂前,请确保已经阅读并理解了如下两篇⽂章:<正⽂>引⼊这是⼀种由THU −zkw ⼤佬发明的数据结构,本质上是经典的线段树区间划分思想,采⽤了⾃底向上的⽅式传递区间信息,避免的递归结构,其代码相对经典线段树更简单,常数更⼩,易于实现。

统计的⼒量-源⾃。

基础⾮递归接下来,我们将讲解zkw 线段树的第⼀种实现形式,⽤于单点修改 区间查询,我们以查询区间最⼤值为例来讲解。

建树普通线段树需要建树,zkw 线段树当然也需要建树。

考虑线段树的⼀个性质,其树上的叶节点代表的往往都是形如[x ,x ]的元区间,⽽且除最后⼀层外,线段树是⼀颗满⼆叉树,所以我们要把这颗线段树的数组⼤⼩先申请好了。

⼀棵满⼆叉树有x 个节点时,它有x +12个叶⼦节点,⽽我们需要⾄少n 个叶⼦节点的线段树,即使x +12≥n ,那么我们设x =1,在x +12<n 时不断执⾏x ∗=2,就能得到⾜够⼤⼩的线段树下标base ,由于线段树的叶⼦节点可能分布在两层,所以保险起见,我们还需再将x 扩⼤⼀倍,即在x +1<n 时不断执⾏x ∗=2就可以了。

得到合适的下标位置后,将1−n 下标位置的原数据直接存⼊线段树的叶⼦节点即可。

其实,我们还需将下标再扩⼤两个位置,即需要保证x >n ,才停⽌执⾏x ∗=2。

其原因是这样的:在执⾏区间查询操作时,我们需要将查询区间[l ,r ]更改为(l ,r )(关于原因,我们之后再分析),才便于zkw 线段树的查询,那么在询问[1,n ]时,可能为调⽤到[0,n +1]的原下标,所以还需再扩⼤两个位置。

得到了合适的下标base 并将1−n 的数据存⼊对应位置后,当然我们还要对1到base −1的线段树位置进⾏区间更新,这个普通的更新就可以了。

Code :单点修改直接在叶节点上修改对应的值,然后更新其每⼀个⽗节点即可。

线段树

线段树
h log(2n 1) O(log n) 。
对于线段树中的每个结点, 其表示一个区间,我们可以记录和这个区间相关 的一些信息(如最大值、最小值、和等) ,但要满足可二分性,即能直接由其子
结点的相关信息得到。 对于询问区间信息和修改区间信息的操作,线段树一般在能 O(log n) 的时间 内完成,而且常数相对较小(和后面的伸展树比较) ,算是一种高效实用的数据 结构。 (2)线段树的基本操作——查询区间信息 使用线段树的目的就是能高效地查找和修改区间信息, 下面先介绍第一个操 作——查询操作。 对于当前要查询的区间 a, b ,我们从线段树的根结点开始,如果当前结点 表示的区间被查询区间完全包含,那么更新结果,否则分别考察左右子结点,如 果查询区间与某个子结点有交集(也可能两个都有) ,那么就递归考察这个子结 点。代码框架如下1:
对于任意一个区间,会被划分成很多在线段树上存在的区间,可以证明,划 分出来的区间在线段树的每层最多有两个,又因为线段树的深度为 O(log n) ,因 此查询操作的时间复杂度为 O(log n) 。
(3)线段树的基本操作——修改区间信息 相对于查询区间信息,修改区间信息显得稍微复杂一些。
1
本文中的代码均使用 C++语言描述
(4)线段树特点总结 利用线段树, 我们可以高效地询问和修改一个数列中某个区间的信息,并且 代码也不算特别复杂。 但是线段树也是有一定的局限性的, 其中最明显的就是数列中数的个数必须 固定,即不能添加或删除数列中的数。对于这个问题,下面介绍的伸展树就可以 完美的解决。
(7,10]
(0,1] (1,2] (2,3] (3,5] (5,6]
(6,7] (7,8]
(8,10]
(3,4]

线段树ppt课件

线段树ppt课件


else Count := 0; 连接处颜色相同并且
非底色,则总数减1
统计算法
最左边的颜色
• end • else if r – l > 1 then
最右边的颜色
• begin
最左颜色=最右颜色=本身

result := Count(p * 2, l,非(底l +色则r)统d计iv数加2,1 lc, tl) +

else if a >= m then Insert(p * 2 + 1, m, r, a, b, c)

else begin

Insert(p * 2, l, m, a, m, c);

Insert(p * 2 + 1, m, r, m, b, c);

end;

end;
• end;
• end;
示例
• 初始情况 0 0 0 0 0
• [1,2]
10000
• [3,5]
10110
• [4,6]
10111
• [5,6]
10111
4个1
缺点
• 此方法的时间复杂度决定于下标范围的平 方。
• 当下标范围很大时([0,10000]),此方法 效率太低。
离散化的做法
• 基本思想:先把所有端点坐标从小到大排 序,将坐标值与其序号一一对应。这样便 可以将原先的坐标值转化为序号后,对其 应用前一种算法,再将最后结果转化回来 得解。
Wall
分析
• 这道题目是一个经典的模型。在这里,我 们略去某些处理的步骤,直接分析重点问 题,可以把题目抽象地描述如下:x轴上有 若干条线段,求线段覆盖的总长度。

线段树 区间最大值 模板

线段树 区间最大值 模板

线段树区间最大值模板线段树是一种二叉树的数据结构,它被广泛应用于解决与区间相关的问题。

其中,区间最大值是线段树的一个常见应用。

在本文中,我将详细介绍线段树的概念和实现,并提供一个用于解决区间最大值问题的模板。

1. 线段树的概念线段树是一种将区间划分为多个子区间并以二叉树形式表示的数据结构。

每个节点代表一个区间,并保存该区间的一些属性,例如区间的最大值、最小值、总和等。

通过将区间逐层划分为子区间,线段树可以高效地处理区间操作。

2. 线段树的实现线段树的实现可以使用数组或链表。

在这里,我将使用数组来实现线段树。

2.1 初始化线段树首先,我们需要定义一个数组来表示线段树。

对于给定的区间,我们可以使用递归的方式将其划分为左右子区间,直到区间的长度为1。

然后,我们将每个区间的最大值保存在线段树的相应节点中。

2.2 更新线段树当某个区间的值发生改变时,我们需要更新线段树中相应的节点。

首先,我们找到包含要更新的值的叶子节点,并更新该节点的值。

然后,我们通过递归地向上更新父节点的值,直到根节点。

2.3 查询线段树查询线段树的最大值需要考虑两种情况。

如果查询的区间与当前节点的区间完全重叠,那么我们可以直接返回该节点保存的最大值。

否则,我们需要继续向下递归查询左右子节点,并返回两者中的最大值。

3. 线段树区间最大值的模板下面是一个用于解决区间最大值问题的线段树模板:```#include <iostream>#include <vector>#include <climits>using namespace std;// 定义线段树节点的数据结构struct SegmentTreeNode {int start;int end;int max_value;SegmentTreeNode* left;SegmentTreeNode* right;SegmentTreeNode(int s, int e) : start(s), end(e), max_value(INT_MIN),left(nullptr), right(nullptr) {}};// 构建线段树SegmentTreeNode* buildSegmentTree(vector<int>& nums, int start, int end) { if (start > end) return nullptr;SegmentTreeNode* root = new SegmentTreeNode(start, end);if (start == end) {root->max_value = nums[start];} else {int mid = start + (end - start) / 2;root->left = buildSegmentTree(nums, start, mid);root->right = buildSegmentTree(nums, mid + 1, end);root->max_value = max(root->left->max_value, root->right->max_value); }return root;}// 更新线段树中的值void updateSegmentTree(SegmentTreeNode* root, int index, int value) {if (!root) return;if (root->start == root->end) {root->max_value = value;} else {int mid = root->start + (root->end - root->start) / 2;if (index <= mid) {updateSegmentTree(root->left, index, value);} else {updateSegmentTree(root->right, index, value);}root->max_value = max(root->left->max_value, root->right->max_value);}}// 查询线段树中的最大值int querySegmentTree(SegmentTreeNode* root, int start, int end) {if (!root) return INT_MIN;if (root->start == start && root->end == end) {return root->max_value;} else {int mid = root->start + (root->end - root->start) / 2;if (end <= mid) {return querySegmentTree(root->left, start, end);} else if (start > mid) {return querySegmentTree(root->right, start, end);} else {return max(querySegmentTree(root->left, start, mid), querySegmentTree(root->right, mid + 1, end));}}}int main() {vector<int> nums = {1, 3, 5, 7, 9, 11};int n = nums.size();SegmentTreeNode* root = buildSegmentTree(nums, 0, n - 1);updateSegmentTree(root, 2, 10);int max_value = querySegmentTree(root, 1, 4);cout << "Max value in range [1, 4]: " << max_value << endl;return 0;}```这是一个完整的线段树模板,可以根据具体的问题进行修改和扩展。

线段树详解及例题

线段树详解及例题

线段树详解及例题一、线段树的概念线段树(Segment Tree)是一种用于解决区间查询问题的数据结构,常用于静态区间查询和动态区间查询,也被称为区间树。

二、线段树的构建线段树是一棵二叉树,其每个节点都代表一个区间。

首先,我们将待处理的区间按照二叉树的方式进行划分,生成一棵满二叉树。

这里我们以求一段区间内元素的和为例:(1)首先,将整个区间 $[1,n]$ 分为两个部分,设左边区间为$[1,mid]$,右边区间为 $[mid+1,n]$。

这里的 $mid$ 是 $(1+n)/2$ 的值。

(2)然后,将左区间和右区间再分别划分成两个子区间并进行相加,直到区间大小为 1,构建出一棵完整的线段树。

三、线段树的维护构建好线段树之后,我们需要对其进行维护,以便能够快速地查询给定区间的值。

设线段树中某个节点代表区间 $[l,r]$,那么这个节点的值等于 $[l,r]$ 区间中所有元素的和。

如果需要对线段树进行更新,我们可以利用递归的方式向下更新每个节点的值。

当需要将 $[l,r]$ 区间中的某个元素修改为 $x$ 时,我们可以将其视为将线段树上区间 $[l,r]$ 的值都减去原来元素的值再加上 $x$。

四、线段树的查询线段树的查询包括单点查询和区间查询两种方式:(1)单点查询:即查询线段树中某个节点所代表的区间的值。

(2)区间查询:即查询线段树中 $[l,r]$ 区间内所有元素的和。

五、应用实例下面通过几道例题来说明线段树的应用。

问题一:给定一个序列,更新其中某个元素的值,并求出其区间和。

样例输入:8 1 3 -4 2 8 10 9 62 5 2样例输出:17问题二:对一个序列进行 $m$ 次操作,每次操作为在 $L$ 到 $R$ 的区间内加上 $c$,并输出最终改变后的序列。

样例输入:5 31 3 23 5 32 4 1样例输出:2 5 4 0 2以上就是关于线段树的详细介绍和几个应用示例,希望可以对读者有所帮助。

线段树的概念与应用

线段树的概念与应用

线段树的概念与应用线段树(Segment Tree)是一种用于解决区间查询问题的数据结构。

它可以高效地支持以下两种操作:区间修改和区间查询。

线段树的应用非常广泛,在离线查询、区间统计、区间更新等问题中有着重要的作用。

一、概念线段树是一颗二叉树,其中每个节点代表了一个区间。

根节点表示整个待查询区间,而叶子节点表示的是单个元素。

每个内部节点包含了其子节点所代表区间的并集。

二、构建线段树线段树的构建过程是自底向上的。

将待查询数组划分成一颗满二叉树,并将每个区间的和存储在相应的节点中。

对于叶子节点,直接存储对应元素的值。

而非叶子节点的值可以通过其子节点的值计算得到。

三、线段树的查询对于区间查询操作,可以通过递归方式实现。

从根节点开始,判断查询区间和当前节点所代表的区间是否有交集。

若没有交集,则返回当前节点的默认值。

若查询区间包含当前节点所代表的区间,则返回当前节点存储的值。

否则,将查询区间分割成左右两部分继续递归查询。

四、线段树的更新对于区间更新操作,也可以通过递归方式实现。

与查询操作类似,首先判断查询区间和当前节点所代表的区间的关系。

若没有交集,则无需更新。

若查询区间包含当前节点所代表的区间,则直接更新当前节点的值。

否则,将更新操作分割成左右两部分继续递归更新。

五、应用案例:区间最值查询一个常见的线段树应用是求解某个区间的最值。

以查询区间最小值为例,可以通过线段树来高效地解决。

首先构建线段树,然后进行区间查询时,分为以下几种情况处理:若当前节点所代表的区间完全包含于查询区间,则直接返回该节点的值;若当前节点所代表的区间与查询区间没有交集,则返回默认值;否则,将查询区间分割成左右两部分继续递归查询,最后返回两个子区间查询结果的较小值。

六、总结线段树是一种非常有用的数据结构,能够高效地解决区间查询问题。

通过合理的构建和操作,线段树可以应用于多种场景,如区间最值查询、离线查询等。

熟练掌握线段树的概念和应用方法,对解决问题具有重要意义。

文档:线段树及其应用

文档:线段树及其应用

线段树及其应用常州市教育教研室、常州市第一中学林厚从2009-4-13一、为什么要用线段树例1.有一列数,初始值全部为0。

每次可以进行以下三种操作中的一种:(1)给指定区间的每个数加上一个特定值;(2)将指定区间的所有数置成一个统一的值;(3)询问一个区间上的最小值、最大值、所有数的和。

[问题分析]在最朴素的模拟算法中,通常用线性表存储整个数列,然后在执行这三种操作的过程中,对每个在处理区间或是询问区间中的元素逐一进行处理。

假设这个数列的长度为n,总操作数为m,那么这个算法每次维护的时间复杂度为O(n),整体的时间复杂度为O(mn)。

当m与n比较小的时候,这无疑是一个不错的策略。

但是如果m与n的值比较大,那么这个算法显然就太低效了。

这个算法低效的一个重要原因就是:所有的维护都是针对元素的,而题目中所有的维护都是针对区间的。

所以,我们的优化也就应该从这里着手。

假如我们设计一种数据结构,能够直接维护所需处理的区间,那么就能更加有效地解决这个问题了。

线段树就是这样一种数据结构。

它能够将我们需要处理的区间不相交的分成若干个小区间,每次维护都可以在这样一些分解后的区间上进行,并且查询的时候,我们也能够根据这些被分解了的区间上的信息合并出整个询问区间上的查询结构。

二、线段树的结构定义1:长度为1的线段称为元线段。

定义2:一棵树被称为线段树,当且仅当这棵树满足如下条件:(1)该树是一棵二叉树;(2)树中的每一个结点都对应一条线段[a,b];(3)树中的结点是叶子结点,当且仅当它所代表的线段是元线段;(4)树中非叶子结点都有左右两棵子树,左子树树根对应线段[a ,(a+b)/2],右子树树根对应线段[(a+b)/2,b]。

通俗地说,线段树是一棵二叉树,树中的每一个结点表示了一个区间[a,b]。

每一个叶子结点上a+1=b,这表示了一个初等区间。

对于每一个内部结点b-a>1,设根为[a,b]的线段树为T(a,b),则进一步将此线段树分为左子树T(a,(a+b)/2),以及右子树T((a+b)/2,b),直到分裂为一个初等区间为止。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

(3)对区间修改(统一加上一个数) )对区间修改(统一加上一个数)
procedure update(cur:Node;l,r,delta:integer); var LC,RC:Node; //需要给每个区间增加一个变量delta begin LC:=cur^.LeftChild; RC:=cur^.RightChild; if (l<=cur^.Left) and (cur^.Right<=r) then cur^.Delta:=cur^.Delta+delta //改变该区间的delta,注意sum else begin if l<=(cur^.Left+cur^.Right) div 2 then update(LC,l,r,delta); if r>(cur^.Left+cur^.Right) div 2 then update(RC,l,r,delta); cur^.Sum:=LC^.Sum+LC^.Delta*(LC^.Right-LC^.Left+1); cur^.Sum:=cur^.Sum+RC^.Sum+ //上推 RC^.Delta*(RC^.Right-RC^.Left+1); end; end;
为什么要用线段树? 为什么要用线段树?
一般的模拟算法: 用一张线性表表示整个数列,每次执行前两个 操作的时候,将对应区间里的数值逐一进行修改, 执行第三个操作的时候,线性扫描询问区间,求出 三个统计值,每次维护的时间复杂度O(m),整体 的时间复杂度O(mn)。
为什么要用线段树? 为什么要用线段树?
(5)对区间修改(设置为同一个数) )对区间修改(设置为同一个数)
procedure update(cur:Node;l,r,num:integer); var LC,RC:Node; begin LC:=cur^.LeftChild; RC:=cur^.RightChild; if cur^.En //如果该区间已经是同一个值,将值下传给左右区间 then begin cur^.sum:=(cur^.right-cur^.left+1)*cur^.data; if LC<>nil then begin LC^.Data:=cur^.Data; LC^.En:=true; end; if RC<>nil then begin RC^.Data:=cur^.Data; RC^.En:=true; end; cur^.En:=false; end; if (l<=cur^.Left) and (cur^.Right<=r) then begin cur^.En:=true; cur^.Data:=num; end else begin if l<=(cur^.Left+cur^.Right) div 2 then update(LC,l,r,num); if r>(cur^.Left+cur^.Right) div 2 then update(RC,l,r,num); cur^.Sum:=calcsum(LC)+calcsum(RC); end; end;
线段树的基本操作及实现
线段树的查询
procedure query(cur:Node;l,r:integer); var LC,RC:Node; begin LC:=cur^.LeftChild; RC:=cur^.RightChild; if (l<=cur^.Left) and (cur^.Right<=r) then writeln(cur^.Left,‘ ’,cur^.Right); //可以增加其他操作 else begin if l<=(cur^.Left+cur^.Right) div 2 then query(LC,l,r); if r>(cur^.Left+cur^.Right) div 2 then query(RC,l,r); end; end;
readln(m,n); for i:=1 to n do begin read(t); if t=1 //指定区间加上一个值 if t=2 //指定区间置成一个值 then begin then begin readln(left,right,x); readln(left,right,x); for j:=left to right do for j:=left to right do a[j]:=a[j]+x; a[j]:=x; end; end;
线段树的结构
如T(1,10)的结构:
[1,10]
[1,5] [1,3] [1,2] [2,3] [3,5] [3,4] [4,5] [5,6] [5,7] [6,7]
[5,10] [7,10] [7,8] [8,10]
[8,9]
[9,10]
线段树的结构
常用的是需要对数列进行处理,将区间[a,b]分 解为[a,(a+b)/2],[(a+b)/2+1,b],当a=b时表示为一 个叶子结点,表示数列中的一个数。
线段树(区间树) 线段树(区间树)
线段树的结构
定义1:长度为1的线段称为元线段。 定义2:一棵树被称为线段树,当且仅当这棵树满 足如下条件: (1)该树是一棵二叉树; (2)树中的每一个结点都对应一条线段[a,b]; (3)树中的结点是叶子结点,当且仅当它所代 表的线段是元线段; (4)树中非叶子结点都有左右两棵子树,左子 树树根对应线段[a,(a+b)/2],右子树树根对应线段 [(a+b)/2,b]。
[1,10] [1,5] [1,3] [1,2] [1,1] [2,2] [3,3] [4,5] [4,4] [5,5] [6,6] [6,7] [7,7] [6,8] [8,8] [6,10] [9,10] [9,9] [10,10]
线段树的性质
性质1:长度范围为[1,L]的一棵线段树的深度不超 过log2(L-1)+1; 性质2:线段树上的结点个数不超过2L个; 性质3:线段树把区间上的任意一条线段都分成不 超过2log2L条线段。
线段树及其应用
江苏省华罗庚中学 杨志军 oldsheep@
为什么要用线段树? 为什么要用线段树?
例1:有M个数排成一列,初始值全为0,然后做N 次操作,每次我们可以进行如下操作: (1)将指定区间的每个数加上一个值; (2)将指定区间的所有数置成一个值; (3)询问一个区间上的最小值、最大值、所有数 的和。
(1)对元素进行修改 )
procedure insert(cur:Node;x,num:integer); var LC,RC:Node; begin LC:=cur^.LeftChild; RC:=cur^.RightChild; if cur^.Left=cur^.Right //对叶结点的处理 then begin cur^.Min:=num; cur^.Max:=num; cur^.Sum:=num; end else begin if x<=(cur^.Left+cur^.Right) div 2 then insert(LC,x,num); if x>(cur^.Left+cur^.Right) div 2 then insert(RC,x,num); cur^.Sum:=LC^.Sum+RC^.Sum; //上推 if (LC^.Max>RC^.Max) then cur^.Max:=LC^.Max else cur^.Max:=RC^.Max; if (LC^.Min<RC^.Min) then cur^.Min:=LC^.Min else cur^.Min:=RC^.Min; end; end;
时间复杂度是线性的! 时间复杂度是线性的!
为什么要用线段树? 为什么要用线段树?
当m、n的值比较大时,这个算法就太低效了。 其低效的原因主要是我们在每一次操作中都是针对 每个元素进行维护的,而这里我们进行的操作都是 针对一个区间进行操作的。 假如设计一种数据结构,能够直接维护所需处 理的区间,那么就能更加有效地解决这个问题。
为什么要用线段树? 为什么要用线段树?
if t=3 //询问一个区间的最小值、最大值、和 then begin readln(left,right); min:=a[left]; max:=a[left]; sum:=a[left]; for j:=left+1 to right do begin if a[j]<min then min:=a[j]; if a[j]>max then max:=a[j]; sum:=sum+a[j]; end; writeln(min,' ',max,' ',sum); end;
线段树的维护方法
对元素进行修改 修改 对区间进行修改 区间的和 查询 区间的最大值 区间的最小值 其它 设置为同一个数 统一加上一个数
线段树的维护方法
如果想要让线段树发挥实际的作用,必须在每 个结点上维护额外的域来记录更多的信息。 首先看一个引例的弱化版,假设每次修改操作 只能对其中某个元素进行修改。 在每个结点上额外维护3个域:max、min、 sum,分别表示子树上的最大值、最小值和所有元 素的和。
为什么要用线段树? 为什么要用线段树?
机器配置: 机器配置:Pentium 1.3G 512M
M,N的规模 的规模 M=100000,N=5000 M=100000,N=10000 M=100000,N=50000 M=100000,N=100000
一般的模拟 2.06秒 秒 4.14秒 秒 21.32秒 秒 43.36秒 秒
线段树的基本操作及实现
线段树的构造
procedure build(cur:Node;l,r:integer); begin cur^.Left:=l; cur^.Right:=r; if l=r then begin cur^.LeftChild:=nil; cur^.RightChild:=nil; end else begin new(cur^.LeftChild); new(cur^.RightChild); build(cur^.LeftChild,l,(l+r) div 2); build(cur^.RightChild,(l+r) div 2+1,r); end; end;
相关文档
最新文档