POJ 1785 Binary Search Heap Construction(裸笛卡尔树的构造)
笛卡尔树:
每个节点有2个关键字key、value。从key的角度看,这是一颗二叉搜索树,每个节点的左子树的key都比它小,右子树都比它大;从value的角度看,这是一个堆。
题意:以字符串为关键字key,数字为关键字value,构造一个二叉搜索大堆,最后按要求中序遍历 笛卡尔树的构造。
建立笛卡尔树的O(n)的算法:
从别人博客里拷贝过来的,这里给出链接:http://hi.baidu.com/yy17yy/item/cd4edcf963944f6a3d148553
首先按key关键字进行排序,这样建树的时候从左下角往右下角建。根据定义可知,每个数组的末尾节点必是位于树的最右路上且不可能有右孩子。 在建立树的过程中每次加入一个元素A[X],则该节点一定位于此时的树的最右路上且无右孩子。所以只要沿着A[X-1]节点向上走, 找到比A[X]大的第一个节点A[K],则A[X]是A[K]的右孩子,且A[K]原来的右孩子此时将成为A[X]的左孩子。 若找不到A[K]则此时的树的根将作为A[X]的左孩子,A[X]将成为树的新的根节点。
可以模拟一个虚根,其priority设为无穷,这样最后构造出来的树即为虚根的右子树,方便编写程序。
我原来排序时,是自己写了比较器,传给sort方法,969MS。后来在Node结构体中重载运算符<,625MS。
代码中scanf的用法,详见:http://blog.csdn.net/wesweeky/article/details/6439777
#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>
#include <algorithm>
#include <string> using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=<<;
int fa[maxn]; //存储父节点的编号
int son[maxn][]; //son[i][0]存储i的左儿子编号,son[i][1]存储i的右儿子编号
int n; struct Node{
char s[]; //字符串
int p; //优先级
bool operator<(const Node tmp)const{
return strcmp(s,tmp.s)<;
}
}node[maxn];
/*
bool cmp(const Node tmp1,const Node tmp2){
if(strcmp(tmp1.s,tmp2.s)<0)
return 1;
else
return 0;
}
*/
void treap(int i){
int tmp=i-;
//直到找到一个tmp,使得tmp的优先级大于i
while(node[tmp].p<node[i].p){
tmp=fa[tmp];
}
//tmp的原先的右儿子即为i的左儿子,i成为tmp的右儿子
son[i][]=son[tmp][];
son[tmp][]=i;
fa[i]=tmp;
}
//中序遍历
void dfs(int i){
if(i==)
return;
printf("(");
//递归左儿子
dfs(son[i][]);
printf("%s/%d",node[i].s,node[i].p);
//递归右儿子
dfs(son[i][]);
printf(")");
}
int main()
{
//这里为方便起见,设立了一个优先级很大的虚根,之后建的树为虚根的右子树
node[].p=INF;
while(scanf("%d",&n),n){
memset(son,,sizeof(son));
memset(fa,-,sizeof(fa));
for(int i=;i<=n;i++){
//[a-z]表示读取的字符串由a-z中的字符组成,其余的字符为定界符
scanf(" %[a-z]/%d",node[i].s,&node[i].p);
}
//sort(node+1,node+n+1,cmp);
sort(node+,node+n+);
for(int i=;i<=n;i++){
treap(i);
}
//从虚根的右儿子开始dfs
dfs(son[][]);
printf("\n");
}
return ;
}
POJ 1785 Binary Search Heap Construction(裸笛卡尔树的构造)的更多相关文章
- [POJ1785]Binary Search Heap Construction(笛卡尔树)
Code #include <cstdio> #include <algorithm> #include <cstring> #define N 500010 us ...
- 笛卡尔树 POJ ——1785 Binary Search Heap Construction
相应POJ 题目:点击打开链接 Binary Search Heap Construction Time Limit: 2000MS Memory Limit: 30000K Total Subm ...
- POJ 1785 Binary Search Heap Construction (线段树)
题目大意: 给出的东西要求建立一个堆,使得后面的数字满足堆的性质.并且字符串满足搜索序 思路分析: 用线段树的最大询问建树.在建树之前先排序,然后用中序遍历递归输出. 注意输入的时候的技巧. .. # ...
- ZOJ - 2243 - Binary Search Heap Construction
先上题目: Binary Search Heap Construction Time Limit: 5 Seconds Memory Limit: 32768 KB Read the sta ...
- POJ 2559 Largest Rectangle in a Histogram ——笛卡尔树
[题目分析] 本来是单调栈的题目,用笛卡尔树可以快速的水过去. 把每一个矩阵看成一个二元组(出现的顺序,高度). 然后建造笛卡尔树. 神奇的发现,每一个节点的高度*该子树的大小,就是这一块最大的子矩阵 ...
- poj1785 Binary Search Heap Construction
此题可以先排序再用rmq递归解决. 当然可以用treap. http://poj.org/problem?id=1785 #include <cstdio> #include <cs ...
- 牛客多校第一场 A Equivalent Prefixes 单调栈(笛卡尔树)
Equivalent Prefixes 单调栈(笛卡尔树) 题意: 给出两个数组u,v,每个数组都有n个不同的元素,RMQ(u,l,r)表示u数组中[l,r]区间里面的最小值标号是多少,求一个最大的m ...
- [hdu1506 Largest Rectangle in a Histogram]笛卡尔树
题意:http://acm.hdu.edu.cn/showproblem.php?pid=1506 如图,求最大的矩形面积 思路: 笛卡尔树:笛卡尔树是一棵二叉树,树的每个节点有两个值,一个为key, ...
- POJ-1785-Binary Search Heap Construction(笛卡尔树)
Description Read the statement of problem G for the definitions concerning trees. In the following w ...
随机推荐
- Flex设置外部浏览器
Flex Builder默认的外围浏览器是微软 Internet Explorer. 如果想改成Firefox,步骤如下: Window>Preferences>General>We ...
- const关键字在C和C++区别
1)C++默认为内部链接:C默认为外部链接2)在C++中,一般一个const不会创建内存空间,而是将其保存在符号表(待看).比如: ; char buf[bufsize]; 这里无需为const创建内 ...
- 更改windows服务的配置文件app.config
/// <summary> /// 获取每次处理记录数 /// </summary> /// <returns></returns> private s ...
- js Table冻结表头示例代码
Table冻结表头的js实现代码. Table冻结表头: <script type="text/javascript"> //冻结table的表头 function ...
- 应用js改变问章字体大小
刚来公司的时候领导给分配的都是一些简单的简单的简单的.....任务 一次叫我把文章的字体大小变换功能写出来.在网上搜了很多都不管用!不过功夫不负有心人还是被我找到了!拿出来分享下! <scrip ...
- 原始套接字的简单tcp包嗅探
原始套接字 sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP); while(1) { data_size = recvfrom(sock_raw ...
- Linq to Entities
首先要添加一个ADO.NET实体数据模型 添加一个Entities 对象,其用法和linqtosql类似例如: StudentInfoEntities2 entity = new StudentInf ...
- 用python实现两个文本合并
一段时间前在网上看到一段面试题,要求如下: employee文件中记录了工号和姓名 cat employee.txt: 100 Jason Smith 200 John Doe 300 Sanjay ...
- 用Tupper自我指涉公式造图
塔珀自指公式是杰夫·塔珀(Jeff Tupper)发现的自指公式:此公式的二维图像与公式本身外观一样.此公式在众多数学与计算机科学课程里被用作绘制公式图像的练习作业. 公式最初于他2001年SIGGR ...
- MySQL监控工具-orzdba
源代码地址:http://code.taobao.org/p/orzdba/src/trunk/ [root@hank-yoon servers]# chmod +x orzdba 在代码的1 ...