标签:cur 笛卡尔 笔记 建树 学习 Treap 节点 树是
众所周知,笛卡尔树是联赛考纲内的内容
定义
笛卡尔树是一种二叉树,每一个结点由一个键值二元组(k,w)构成。要求k满足二叉搜索树的性质,而w满足堆的性质。
如果k,w已知,且互不相同,则符合定义的笛卡尔树唯一。
线性建树
如果序列的第一维有序,我们可以利用单调栈在O(n)的时间内完成笛卡尔树的构建。
不妨假设第一维降序排序,以小根堆为例,每当我们向树中插入一个权值,为了满足二叉搜索树性质,其必然插入在树的右链。如果它的父亲节点第二维大于其第二维的值,我们对该节点进行左旋操作(不明白的话请参考讲解平衡树的博客的),直至其满足堆的性质。
如果你学过Treap,会发现这就是Treap的操作(事实上,Treap就是一种笛卡尔树)
因为每个节点最多在右链上出现一次(左旋之后父亲节点被移到了左链上),我们使用单调栈来维护其右链上的节点。
代码:
点击查看代码
void build() {
for(int i=1;i<=n;i++) {
cur=top;
while(cur && a[s[cur]] > a[i]) cur--;
if(cur) r[s[cur]]=i;
if(cur < top) l[i]=s[cur+1];
s[++cur]=i;
top=cur;
}
}
一般情况建树
我们对第一维排序后,即可使用上述算法建树。
代码略
标签:cur,笛卡尔,笔记,建树,学习,Treap,节点,树是 来源: https://www.cnblogs.com/cbxz/p/15490337.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。