cogs2840. 二叉查找树

Posted turkeyghb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cogs2840. 二叉查找树相关的知识,希望对你有一定的参考价值。

二叉查找树

 

 

时间限制:1 s   内存限制:512 MB

【题目描述】

 

二叉查找树是一种特殊的二叉树(每个节点最多只有两个儿子的树)。树的每个节点上存有一个唯一的值,并且满足:这个节点的左子树内所有点的值都比这个节点的值小,且右子树内所有点的值都比这个节点的值要大。

对于一棵二叉查找树T,我们可以将一个值为 x的新点插入 T中,且保持树的性质。算法如下:

技术分享图片

需要将 x 插入树 T时,执行 insert(x,T.root)。

 

现在有 N 个数需要插入一棵空树中。给定插入序列,请在每个元素被插入之后,输出所有节点的深度总和(根的深度为 0)。

【输入格式】

 

输入的第一行一个整数 n,表示序列长度。

 

接下来一行n个数是序列中的数字,这些数字是各不相同的,在[1, n]区间。

【输出格式】

 

 

输出 n 行,第 i 行整数表示第 i个数插入树后,至这个节点的节点深度总和。

 

 

【样例输入】

8
3 5 1 6 8 7 2 4

【样例输出】

0
1
2
4
7
11
13
15

【数据规模与约定】

 

对于 50%的数据,满足n ≤ 1000

对于100%的数据,满足n ≤ 3 ∗ 1e5

 

【来源】

qbxt 2017.10.7 t1

 

 

我们可以发现,这棵二叉搜索树构建完毕之后,根节点总是比他的子树内任意一个节点先插入 ,而直接构造是n^2级别的,我们需要知道有一种东西叫笛卡尔树,其实就是一颗treap,既满足二叉搜索树的性质,又满足堆的性质,对于任意一个节点有两个值,key和fix,key满足二叉搜索树,fix满足堆,如果key是按大小顺序插入的,那么我们可以在O(n)的时间内构造出这棵树,那么我们就按题目中所给数字大小顺序插入,fix值为其插入时间,就可以构造出符合题目的那棵树了。(key和fix给定时可以唯一确定一棵树)

技术分享图片
 1 #include<cstdio>
 2 #define ll long long
 3 using namespace std;
 4 const int inf=3e5+10;
 5 int fix[inf],n,fa[inf],dep[inf],a[inf];
 6 ll ans;
 7 int main()
 8 {
 9     scanf("%d",&n);
10     for(int i=1;i<=n;i++){
11         scanf("%d",&a[i]);
12         fix[a[i]]=i;
13     }
14     for(int i=1;i<=n;i++){
15         int last=0,f=i-1;
16         while(fix[f]>fix[i])last=f,f=fa[f];
17         fa[i]=f;
18         fa[last]=i;
19     }
20     dep[0]=-1;
21     for(int i=1;i<=n;i++){
22         dep[a[i]]=dep[fa[a[i]]]+1;
23         ans+=dep[a[i]];
24         printf("%lld\n",ans);
25     }
26     return 0;
27 }
View Code

 

以上是关于cogs2840. 二叉查找树的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段

数据结构 动态查找与二叉排序树

二叉查找树

PHP 二叉查找树(二叉搜索树)的查找

C++-二叉搜索树的查找&插入&删除-二叉搜索树代码实现-二叉搜索树性能分析及解决方案

二叉查找树 - 删除查找