题目链接:http://codeforces.com/problemset/problem/675/D

题意:给一个由n个互异整数组成的序列a[],模拟BST的插入过程,依次输出每插入一个元素a[i]后a[i]的父节点。

数据范围:n [2, 10^5]

思路:直接模拟一般的BST而不维护平衡性的话,有可能会出现极度不平衡甚至退化的情况,复杂度会从O(nlogn)上升到O(n^2)。因此要用平衡二叉树。

可以利用STL中的set容器,但对于题目所要找的“父节点”,set并不提供接口。这时就要考察BST的一些性质推导出解法。

回顾二叉树的中序遍历,对节点prev的直接后继succ的定位操作分两种情况。注意等价BST的“上下可变,左右不乱”的性质,不论是否进行了等价变换,中序遍历序列中任意两个互为直接前驱和直接后继的元素,其层次关系必然为如下两种之一:

1. succ层次更深

=> 由顺序性,succ必为prev的右子树中的节点,故prev的右子树必非空

  且由“直接性”,succ的左孩子必为空。

  对于v小于全局最小值的边界情况,prev及其左子树为空。

2. prev层次更深

=> 由顺序性,prev必为succ的左子树中的节点,故succ的左子树必非空

  且由“直接性”,prev的右孩子必为空。

  对于v大于全局最大值的边界情况,succ及其右子树为空。

对于一个新的待插入的节点v,我们在当前BST的中序遍历序列 s 中进行二分查找,得到应插入的位置的后继元素的位置succ(“大于v的第一个元素,即upper_bound”),然后得到prev=succ-1。为了保证BST的顺序性,v必然要插在prev和succ之间。

从树的结构上看,可以插在标有“必为空”的位置,它恰好介于prev和succ之间,顺序性必然得到保证。具体地,即“succ和prev中更深的那个”,1、2两种情况分别对应succ和prev。如何确定是哪种情况呢?

我们回到对这两种情况的描述上:刚刚所做的推导是否可逆呢?如果可逆,那么我们可以通过判断succ或prev的左右孩子是否为空就可以得知是哪种情况。

分析发现,确实可逆:

1. succ的左孩子为空 => 由顺序性,prev必为succ的祖先 => succ层次更深。

2. prev的右孩子为空 => 由顺序性,succ必为prev的祖先 => prev层次更深。

到此,可以着手设计算法了。首先用set维护平衡二叉树,每次插入节点v前,调用set的lower_bound(或upper_bound,元素互异故二者无差别) 得到“大于v的第一个元素”,即插入v后v的直接后继,记录为迭代器succ。然后得到succ的直接前驱的迭代器prev = succ - 1。

对于左右孩子情况的记录,我没有想到方法,CF题解给出的是维护两个map<int, int>left, right,left记录节点对<v, lc>,right记录节点对<v, rc>。每次插入前通过判断left[succ]和right[prev]是否为空来判断父节点是谁,以及v作为左孩子还是右孩子插入,更新map。

其实这两种情况是对立的,因此一次判断就可确定属于哪种。

 #include <cstdio>
#include <cstring>
#include <set>
#include <map>
using namespace std;
const int MAX_N = ; int n;
struct Node
{
int d;
int lc, rc;
Node(){}
Node(int d):d(d), lc(-), rc(-){}
}nodes[MAX_N]; int a[MAX_N]; int main()
{
while(~scanf("%d", &n)){
for(int i=; i<n; i++){
scanf("%d", &a[i]);
}
set<int> s;
map<int, int> left;//<节点,左孩子>
map<int, int> right; //<节点,右孩子>
int res;
s.insert(a[]);
for(int i=; i<n; i++){
set<int>::iterator pos = s.lower_bound(a[i]);//直接后继
if(pos != s.end() && left.count(*pos)==){//后继没有左孩子,插到后继的左孩子位置
res = *pos;
left[*pos] = a[i];
}else{//后继有左孩子,或没有后继,插到前驱的右孩子位置
pos--;
res = *pos;
right[*pos] = a[i];
}
printf("%d ", res);
s.insert(a[i]);
}
printf("\n");
}
return ;
}

p.s: CF题解的代码好优美,学习了。

【CF 675D Tree Construction】BST的更多相关文章

  1. CF 675D——Tree Construction——————【二叉搜索树、STL】

    D. Tree Construction time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  2. B. Lost Number【CF交互题 暴力】

    B. Lost Number[CF交互题 暴力] This is an interactive problem. Remember to flush your output while communi ...

  3. 3.26-3.31【cf补题+其他】

      计蒜客)翻硬币 //暴力匹配 #include<cstdio> #include<cstring> #define CLR(a, b) memset((a), (b), s ...

  4. 【Binary Search Tree Iterator 】cpp

    题目: Implement an iterator over a binary search tree (BST). Your iterator will be initialized with th ...

  5. 【cf补题记录】Codeforces Round #608 (Div. 2)

    比赛传送门 再次改下写博客的格式,以锻炼自己码字能力 A. Suits 题意:有四种材料,第一套西装需要 \(a\).\(d\) 各一件,卖 \(e\) 块:第二套西装需要 \(b\).\(c\).\ ...

  6. Codeforces 675D Tree Construction Splay伸展树

    链接:https://codeforces.com/problemset/problem/675/D 题意: 给一个二叉搜索树,一开始为空,不断插入数字,每次插入之后,询问他的父亲节点的权值 题解: ...

  7. 【Cf Edu #47 F】Dominant Indices(长链剖分)

    要求每个点子树中节点最多的层数,一个通常的思路是树上启发式合并,对于每一个点,保留它的重儿子的贡献,暴力扫轻儿子将他们的贡献合并到重儿子里来. 参考重链剖分,由于一个点向上最多只有$log$条轻边,故 ...

  8. 【Count Complete Tree Nodes】cpp

    题目: Given a complete binary tree, count the number of nodes. Definition of a complete binary tree fr ...

  9. codeforces 675D Tree Construction set

    转自:http://blog.csdn.net/qwb492859377/article/details/51447350 #include <stdio.h> #include < ...

随机推荐

  1. sudo nopasswd

    preface,不问头条,但汝读荐,诚意满满的!

  2. MySQL 索引优化全攻略

    所谓索引就是为特定的mysql字段进行一些特定的算法排序,比如二叉树的算法和哈希算法,哈希算法是通过建立特征值,然后根据特征值来快速查找.而用的最多,并且是mysql默认的就是二叉树算法 BTREE, ...

  3. hdu 3711 Binary Number(暴力 模拟)

    Problem Description For non-negative integers x and y, f(x, y) , )=,f(, )=, f(, )=. Now given sets o ...

  4. 多校联赛2 Problem2 Warm up 求桥的数目+缩点后的树的直径 当时被不知道原因的爆栈爆到无语了。。

    Warm up Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total S ...

  5. java与.net比较学习系列(3) 基本数据类型和类型转换

    在Java中,数据类型分为两类,一类是基本数据类型,另外一类是引用类型. 而在C#中,数据类型分为三类,分别是基元类型,值类型和引用类型.其中基元类型是.net framework框架中预定义的类型, ...

  6. SlipButton——滑动开关

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjI1MjUwMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  7. POJ1742:Coins(多重背包)

    Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar. ...

  8. Centos 7 python升级(2.7.5-》2.7.11)

    1.安装升级GCC yum install gcc* openssl openssl-devel ncurses-devel.x86_64  bzip2-devel sqlite-devel pyth ...

  9. CSS彻底研究(3) - 浮动,定位

    Github pages 博文 CSS彻底研究(3)-浮动,定位 一 . 浮动float I . 定义及规则 float默认为none,对应标准流的情况.当float : left;时,元素就会向其父 ...

  10. CSS---------------之文本颜色

    CSS2支持如下名字的颜色 注意点: 你的浏览器有可能支持更多名字,但是在实际用的过程中尽量少使用名字的,因为各个浏览器对颜色的会存在差异:查看颜色可以参考 对于更多地颜色,你可以使用代表红,绿,蓝三 ...