笛卡尔树简介(分类到treap里面)
目 录
-
1笛卡尔树简单介绍
-
2笛卡尔树定义
-
3笛卡尔树的实现
- 3.1 O(N^2)算法实现
- 3.2 O(N)算法实现
-
4相关代码
- 4.1 c++代码
- 4.2 O(N)算法代码
1笛卡尔树简单介绍
2笛卡尔树定义
3笛卡尔树的实现
O(N^2)算法实现
O(N)算法实现
构造笛卡尔树的过程:
使用数据结构栈,栈中保存的始终是右链,即根结点、根结点的右儿子、根结点的右儿子的右儿子……组成的链
并且栈中从栈顶到栈底key依次减小
如果按照从后到前的顺序判断一个元素是否大于A[i],则每次插入的时间复杂度为O(k+1)
k为本次插入中移除的右链元素个数。因为每个元素最多进出右链各一次,所以整个过程的时间复杂度为O(N)。
从前往后遍历A[i],
1.对于每一个A[i],从栈中找出(从栈顶往栈底遍历,或者从数组后往前遍历)第一个小于等于A[i]的元素
2.如果找到,i.parent为sta[k],同时sta[k].r=i,即i为sta[k]的右子树,
3.如果栈中存在比A[i]大的元素 这些元素肯定是出栈了,这个问题最后的代码统一表示。
同时,sta[k+1].parent=i; i.l=sta[k+1] 即sta[K+1]为i的左子树
4.最后i入栈,比i大的A[i]都自动出栈了。
例子如下。
0 1 2 3 4 5 6 7 8 9 .....key
3 2 4 5 6 8 1 9 10 7 .....A,value
stack
0 1 2 3 4 5 6 7 8 ...num
0
1 2 3 4 5
6 7 8
6 9
最后sta[0].parent=-1; 为根节点 即 6 为根节点。
这里给出的是索引从0开始的[0,n-1]
如果题目给出的是[1,n],可以减一回到[0,n-1]上。
#include <iostream>
#include <queue>
using namespace std;
const int maxnum=10;int a[maxnum];
struct node
{int key;int parent;int l;int r;
}tree[maxnum];void Init()
{int i;for(i=0;i<maxnum;i++)tree[i].parent=tree[i].l=tree[i].r=-1; //初始化
}int Build_Tree()
{int i,top,k;int stack[maxnum];top=-1;for(i=0;i<maxnum;i++){k=top;while(k>=0 && a[stack[k]]>a[i]) //栈中比当前元素大的都出栈k--;if(k!=-1) //find it,栈中元素没有完全出栈,当前元素为栈顶元素的右孩子{tree[i].parent=stack[k];tree[stack[k]].r=i;}if(k<top) //出栈的元素为当前元素的左孩子{tree[stack[k+1]].parent=i;tree[i].l=stack[k+1];}stack[++k]=i;//当前元素入栈top=k;//top指向栈顶元素}tree[stack[0]].parent=-1;//遍历完成后的栈顶元素就是根return stack[0];
}void inorder(int node)
{if(node!=-1){inorder(tree[node].l);cout<<tree[node].key<<endl;inorder(tree[node].r);}
}void levelorder(int node)
{queue<int> q;q.push(node);while(!q.empty()){int k=q.front();q.pop();cout<<tree[k].key<<endl;if(tree[k].l!=-1)q.push(tree[k].l);if(tree[k].r!=-1)q.push(tree[k].r);}
}int main()
{int i;Init();for(i=0;i<maxnum;i++){cin>>a[i];tree[i].key=a[i];}int root=Build_Tree();//inorder(root);//levelorder(root);return 0;
}/*
3 2 4 5 6 8 1 9 10 7
*/
笛卡尔树简介(分类到treap里面)相关推荐
- 牛客 - sequence(笛卡尔树+线段树)
题目链接:点击查看 题目大意:给出一个长度为 n 的数列 a 和数列 b ,求 题目分析:不算难的题目,对于每个 a[ i ] 求一下贡献然后维护最大值就好,具体思路就是,先找出每个 a[ i ] 左 ...
- SGU155(笛卡尔树的构造)
题目:http://acm.sgu.ru/problem.php?contest=0&problem=155 题意:给出每个点的两个值key和fix,且所有的key值和fix值都是不相同的,要 ...
- YbtOJ#752-最优分组【笛卡尔树,线段树】
正题 题目链接:http://www.ybtoj.com.cn/problem/752 题目大意 nnn个人,每个人有cic_ici和did_idi分别表示这个人所在的队伍的最少/最多人数. 然后 ...
- 笛卡尔树(Cartesian Tree)
一.简介 笛卡尔树是一种特定的二叉树数据结构,由数组存储.在范围最值.范围top k查询方面广泛应用. 笛卡尔树的性质: 树中的元素满足二叉搜索树性质,要求按照中序遍历得到的序列为原数组序列 树中节点 ...
- HDU - 6305 RMQ Similar Sequence(笛卡尔树)
http://acm.hdu.edu.cn/showproblem.php?pid=6305 题目 对于A,B两个序列,任意的l,r,如果RMQ(A,l,r)=RMQ(B,l,r),B序列里的数为[0 ...
- [算法学习] 线段树,树状数组,数堆,笛卡尔树
都是树的变种,用途不同 [线段树 Interval Tree] 区间管理,是一种平衡树 可看做是对一维数组的索引进行管理.一维数组不需要是排序好的 深度不超过logL 任一个区间(线段)都分成不超过2 ...
- 洛谷 - P4755 Beautiful Pair(笛卡尔树+主席树)
题目链接:点击查看 题目大意:给出一个长度为 n 的数列 a,现在一个数对 ( i , j ) 如果满足 a[ i ] * a[ j ] <=max( a[ i ] ~ a[ j ] ),则称其 ...
- 牛客多校3 - Sort the Strings Revision(笛卡尔树+分治)
题目链接:点击查看 题目大意:给出一个长度为 n 的数字串 s[ 0 ],每个位置的赋值初始时为 s[ i ] = i % 10 ( i ∈ [ 0 , n - 1 ] ),现在有一个长度为 n 的排 ...
- POJ - 2559 Largest Rectangle in a Histogram(笛卡尔树,单调栈实现)
题目链接:点击查看 题目大意:给出一排高度不同,宽度都为 1 的矩形,问拼起来后最大的矩形面积是多少 题目分析:普通做法是用单调栈直接维护,我一直觉得单调栈处理这种矩形问题都比较抽象,也可能是我太菜了 ...
最新文章
- 接口学习笔记(2009.11.24)
- python中并发编程基础1
- mysql的引擎讲解
- 模块-from import导入所有工具
- 通用权限管理系统组件 (GPM - General Permissions Manager) - 支持请求
- 如何升级浏览器_Chrome谷歌浏览器秒变科研神器,让你的效率提升10倍!
- Python中 类和对象调用其他类中的变量和方法
- solid测序列原理_SOLID原理简介
- php root权限执行命令,如何使用PHP执行需要root权限的系统命令
- JavaScript 工作必知(九)function 说起 闭包问题
- Django【基础篇】
- java maven web项目_java maven项目跟web项目区别
- 第十四章:【UCHome二次开发】uchome通用方法
- 数据产品经理的具象化
- 格式工厂怎么将qlv转换成mp4 转换方法最新
- HIT-哈工大数据结构-作业3(C++)
- 【RK3399 GMAC】Linux Debian9 gmac 主控输出clk ,即output模式
- vspy如何在图形面板显示报文_GUI 图形用户界面 [学习笔记]
- 报错:<generator object <genexpr> at 0x7fa9adc46eb0>
- 解析Linux中的系统安全及应用(二)