笛卡尔树(Cartersian Tree)2016.9.12
来源:互联网 发布:口袋妖怪复刻源码 编辑:程序博客网 时间:2024/06/11 18:41
参考:http://blog.csdn.net/zh_qd1014/article/details/6879083(非常值得一看哦
一、
笛卡尔树是一棵二叉树,树的每个节点有两个值,一个为 key,一个为 val
光看 key 的话,笛卡尔树是一棵二叉搜索树,每个节点的左子树的 key 都比它小,右子树都比它大
光看 value 的话,笛卡尔树有点类似堆,根节点的 val是最小(或者最大)的,每个节点的 value 都比它的子树要小(或者大)
二、树的构造
如果 key 值是有序的,那么笛卡尔树的构造是线性的
如果我们要用数组 A[1 ... n] 构造出一棵有 n 个节点的笛卡尔树
为了方便理解,不妨假设每个节点的 key 为数组元素的下标 i,val 为 A[i] 来建树,这样也保证了 key 的有序性
再假设这里的笛卡尔树为一种特殊的最小堆,那么树的根节点是数组 A 中最小元素的下标 i,根节点的左右孩子分别由数组 A[1 ... i-1] 和数组 A[i+1 ... n] 构造
图 1 原数组
图 2 笛卡尔树最终生成结果(节点内容:key 即数组元素下标)(中序遍历可得到原数组)
图 3 笛卡尔树最终生成结果(节点内容:val 即数组元素)
图 4 第一个插入树的节点
图 6 第三个元素的 val 比树中最右边路径上节点 1、2 的 val 都小,将节点 1 设为该节点的左孩子
图 7 第四个元素的 val 比树中最右边路径上节点 3 的 val 大,故成为根节点 3 的右孩子
图 8 第五个节点元素的 val 比树中最右边的路径上的节点 3、4 的 val 都大,故成为节点 4 的右孩子
图 9 第六个节点元素的 val 比树中最右边路径上节点 5 的 val 小,但比节点 4 的 val 大,故成为节点 4 的右孩子,将节点 5 设为该节点的左孩子
图 10 第七个元素的 val 比树中最右边路径上节点 6 的 val 大,故成为节点6的右孩子
图 11 第八个元素的 val 比树中最右边路径上节点 7 的 val 小,但比节点 6 的 val 大,故该节点称为节点 6 的右孩子,节点 7 成为该节点的左孩子
图 12 第九个元素的 val 比树中最右边路径上节点 8 的 val 大,故成为节点 8 的右孩子
图 13 第十个元素的 val 比树中最右边路径上的节点 9、8、6、4 的 val 都小,但比节点 3 的 val 大,故成为节点 3 的右孩子,节点 4 成为该节点的左孩子
构造过程中需要用栈维护笛卡尔树的一条右链,即根结点、根结点的右儿子、根结点的右儿子的右儿子 …… 组成的链,注意这些元素的 key 和 val 都是递增的
每个节点最多入栈、出栈一次,因此时间复杂度为 O(n)
SGU 155 Cartesian Tree
POJ 2201 Cartesian Tree
题意:
建好笛卡尔树后输出每个结点(按照输入的顺序编号)的父亲结点和两个儿子节点的编号
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <cmath>#include <cctype>#include <bitset>#include <ctime>using namespace std;#define REP(i, n) for (int i = 0; i < (n); ++i)typedef long long ll;typedef unsigned long long ull;typedef unsigned int uint;typedef pair<int, int> Pair;const ull mod = 1e9 + 7;const int INF = 0x7fffffff;const int maxn = 5e4 + 10;struct Cartesian { int id, key, val, pre, lson, rson; bool operator < (const Cartesian& a) const { return key < a.key; }};Cartesian tree[maxn];stack<int> Stack;int N;int pos[maxn];int main(){#ifdef __AiR_H freopen("in.txt", "r", stdin);#endif // __AiR_H scanf("%d", &N); for (int i = 1; i <= N; ++i) { tree[i].pre = tree[i].lson = tree[i].rson = 0; } for (int i = 1; i <= N; ++i) { tree[i].id = i; scanf("%d %d", &tree[i].key, &tree[i].val); } sort(tree+1, tree+1+N); pos[tree[1].id] = 1; Stack.push(1); for (int i = 2; i <= N; ++i) { pos[tree[i].id] = i; int father = 0, son = 0; while (!Stack.empty()) { int t = Stack.top(); if (tree[i].val > tree[t].val) { father = t; break; } son = t; Stack.pop(); } tree[i].pre = father; tree[father].rson = i; tree[i].lson = son; tree[son].pre = i; Stack.push(i); } printf("YES\n"); for (int i = 1; i <= N; ++i) { int pos_t = pos[i]; printf("%d %d %d\n", tree[tree[pos_t].pre].id, tree[tree[pos_t].lson].id, tree[tree[pos_t].rson].id); } return 0;}
HDU 1506 Largest Rectangle in a Histogram
POJ 2559 Largest Rectangle in a Histogram
参考:http://blog.csdn.net/ophunter_lcm/article/details/9327235
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <queue>#include <vector>#include <stack>#include <map>#include <cmath>#include <cctype>#include <bitset>#include <ctime>using namespace std;#define REP(i, n) for (int i = 0; i < (n); ++i)typedef long long ll;typedef unsigned long long ull;typedef unsigned int uint;typedef pair<int, int> Pair;const ull mod = 1e9 + 7;const int INF = 0x7fffffff;const int maxn = 1e5 + 10;struct Cartesian { ll val, pre, lson, rson;};Cartesian tree[maxn];ll Stack[maxn];ll n;ll ans = 0;ll build(void);ll dfs(ll root);int main(){#ifdef __AiR_H freopen("in.txt", "r", stdin);#endif // __AiR_H while (scanf("%I64d", &n) != EOF && n != 0) { for (ll i = 1; i <= n; ++i) { tree[i].pre = tree[i].lson = tree[i].rson = 0; } for (ll i = 1; i <= n; ++i) { scanf("%I64d", &tree[i].val); } ll root = build(); ans = 0; dfs(root); printf("%I64d\n", ans); } return 0;}ll build(void){ ll size = 0; Stack[++size] = 1; for (ll i = 2; i <= n; ++i) { ll father = 0, son = 0; while (size != 0) { ll top = Stack[size]; if (tree[i].val > tree[top].val) { father = top; break; } son = top; --size; } tree[i].pre = father; tree[father].rson = i; tree[i].lson = son; tree[son].pre = i; Stack[++size] = i; } return Stack[1];}ll dfs(ll root){ if (root == 0) { return 0; } ll num = dfs(tree[root].lson) + dfs(tree[root].rson) + 1; ll ans_t = num * tree[root].val; if (ans_t > ans) { ans = ans_t; } return num;}
- 笛卡尔树(Cartersian Tree)2016.9.12
- poj2201Cartesian Tree(笛卡尔树)
- 笛卡尔树(Cartesian Tree)
- 笛卡尔树cartesian tree
- sgu 155 Cartesian Tree (poj2201) 笛卡尔树构造
- POJ-2201 Cartesian Tree【笛卡尔树】
- POJ 2201 Cartesian Tree 笛卡尔树
- POJ 2201 Cartesian Tree 【笛卡尔树】
- SGU 155 Cartesian Tree(笛卡尔树)
- POJ 2201 Cartesian Tree (笛卡尔树)
- POJ-2201-Cartesian Tree(笛卡尔树)
- POJ 2201 Cartesian Tree 笛卡尔树
- Right-heavy tree——笛卡尔树
- POJ-2201 Cartesian Tree(笛卡尔树)
- poj 2201 Cartesian Tree 笛卡尔树
- 笛卡尔树
- 笛卡尔树
- 笛卡尔树
- appCan开发:oninput实现动态请求搜索功能例子
- Nginx 配置初始化过程
- App 移动应用中九种导航设计总结及其优缺点分析
- JAVA虚拟机学习实践-IBM HeapAnalyzer
- 从零基础接触java第九章第三节
- 笛卡尔树(Cartersian Tree)2016.9.12
- 友录项目总结(soundpool,Dialog,date,simpledateformate,calendar的使用方法)
- Android编程小技巧
- App性能优化系列3-提升App启动速度之理论基础
- Node.js实现多图片上传
- Nginx hash结构
- 逻辑回归的应用
- 防火墙状态处理-centos
- react native fetch 用法