2015-C++研发附加题第一题
类似笛卡尔树的实现:
http://baike.baidu.com/link?url=nDGlKta6rvBzJ4_xm1TSp-Px05bU6gzgqWx7LnWwnXm5brtOCPJXXXRXeq9ZpIvsfrWkhua4D76oWrt2iQq2WK
从题目可以看出,按 a 来看的话,是一个二叉排序树,按 b 来看的话,是一个大根堆.
然后需要知道一个性质:二叉排序树的中序遍历,可以得到一个递增的序列。
(1) build:
解法1: 将 pair[] 按照 b 大到小排序,这样的话,第一个,肯定就是树的根节点,继续遍历 pair[],按照 a 的值来分配这个结点的位置。
比如 t->a > insert.a , 这样的话,就往t右子树继续找,如果t->a < insert.a ,就往t右子树继续找,每次t 从根节点开始。
这样的效率为 Nlog(N);
解法2: 将 pair[] 按照 a 小到大排序,然后在遍历 pair[] 来构建树,因为排序过,所以带插入地 insert 肯定是在当前树中 a 最大的那个,
这样就会出现两种情况: 1. insert.b > t.b ,则,insert 取代 t 的位置,然后 insert.left = t;
2.insert.b < t.b ,则,继续与 t.right.b 比较,因为,insert.a 是当前最大,肯定去右边,直至出现 1 的情况,或者到一个空子树,则插入。
这样的效率也是为 Nlog(N);
解法3:在解法2的基础上改进,因为每次都是从根节点开始进行比较,就会多需要一点时间,然后,我们就用一个 stack 来保存 根节点,根节点的右子树的结点(栈底为根节点) .....因为插入的 a 是最大的,肯定先跟最右的比较,1.如果 insert.b < stack.top.b ,则,stack.top.right = insert.,然后多了个右结点,进栈;2.如果 insert.b > stack.top.b , 则说明,需要回溯上去,再跟 stack--.top.b 比较,如果出现 1 的情况,则,在那之前的右子树,成为 insert.left. insert 进栈;或者出现,所有栈都出去了,说明这个 insert 即将成为新的树根。利用空间换时间,效率为 O(N);
(2)insert();
解法: 先按照 二叉排序树的性质,按a的大小将其插入为一个叶子结点,插入之后,进行 b 的判断,如果是左子树插入,且 插入的 b 比较大,则以他的父节点进行一次右旋转,反之,如果是在右子树插入,且插入的 b 比较大,则以他的父节点进行一次左旋转;回溯到根结点.
void treap_insert(treap_node*&a,int label,int p)
{
if(!a)
{
a=new treap_node;
a->label=label;
a->p=p;
}
else if(label<a->label)
{
treap_insert(a->left,label,p);
if(a->left->p>a->p)
treap_right_rotate(a);
}
else
{
treap_insert(a->right,label,p);
if(a->right->p>a->p)
treap_left_rotate(a);
}
}
- 从马尔科夫链到吉布斯采样与PageRank
- 关于eventfd,epoll,线程间通信小记
- RNA-seq 检测变异之 GATK 最佳实践流程
- [Python]Matplotlib绘图基础
- Find命令-Linux系统搜索利器
- PHP 代码规范简洁之道
- Linux申请大页内存(mmap)
- perl模块安装大全
- linux lsof命令查看文件占用进程
- 从黑暗走向光明:Python包安装进阶之路
- Centos7.2/7.3集群安装Kubernetes 1.8.4 + Dashboard
- PsySH——PHP交互式控制台
- 如何将 Text, XML, CSV 数据文件导入 MySQL
- hpv病毒基因研究调研
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- php遍历目录&删除指定文件中指定内容
- pow函数问题
- 字节序列操作函数
- 3分钟短文:Laravel是怎么发出一封电子邮件的?
- Elasticsearch 设计模式
- Spring 的 WebSecurityConfigurerAdapter 过滤器
- 03.视频播放器Api说明
- Postfix配置Gmail中继发信
- 使用Syncthing自建私有同步盘
- 05.视频播放器内核切换封装
- sklearn做特征选择
- ResilioSync:公私兼备的同步盘
- 面向对象语言的三大特征: 封装 继承 多态(二)——继承
- 教你如何设置宝塔面板 Brotli压缩
- Message: session not created: This version of ChromeDriver only supports Chrome version 83