POJ 1442 Black Box
来源:互联网 发布:uploadify java demo 编辑:程序博客网 时间:2024/06/03 21:17
上了半个学期的课以后才发现,原来从来没有认真听过的数算实习才是幕后的大BOSS…每次作业的题目都虐到爆,每节课讲的数据结构都是数算课程上面简单数据结构的升级版,第一次靠自己的能力强行AC了Treap,把自己都感动了。
简单总结一下树堆的性质:
1、树堆,顾名思义就是树和堆的结合体,每个结点除了value值以外还增加了一个priority的值,是每个结点的权值,以最大堆为例,权值最大的点始终在堆的顶部,同时又满足搜索二叉树的性质。
2、在插入一个新的节点的时候,先按照搜索二叉树的性质把插入到叶子节点的位置,然后再使用堆的性质把这个节点siftup到对应的位置,这个时候的问题就在于siftup的时候不能单纯的进行交换,而是采用一种叫做旋转的操作,如图所示:
这里以右旋为例,如果X的权值比Y的权值大,就把X和Y的位置互换,然后理所应当地把B接在Y的左孩子结点上(因为B的值比X大比Y小),我在这道题目中的代码实现比较繁琐,不知道有没有更好的方案,我觉得直接模拟实现就好,也需要什么优化。
3、每个结点的权值一般是直接用随机数生成的,这样也导致我每次提交所用的时间都是不一样的= -
4、当我完成树堆的构造之后,输出第i大的数的时候采用的是中序遍历的方法,结果依然TLE(特别想掀桌子),在室友的启发之下,采用了另一种找第k大的数的方法:给每个结点增加一个变量,记录以这个节点为根节点的子树的节点个数,在寻找第k大的数的时候相当于一个在二叉树里面检索某个值的方式来实现,在debug一个多小时之后顺利AC…
#include<iostream>#include<limits.h>#include<memory.h>#include<stdlib.h>#include<cstdio>using namespace std;#define MAXM 30050struct node{ int value; int size; int priority; int fa,lc,rc;};bool operator < (node a, node b){ return a.value < b.value;}int M,N;int real_i = 0;node treap[MAXM];int copy_i = 0;void Find2(int root,int k){ if(!root) return; if(treap[treap[root].lc].size +1 == k){ printf("%d\n",treap[root].value); return; } if(treap[treap[root].lc].size >= k){ Find2(treap[root].lc,k); } else{ Find2(treap[root].rc,k-treap[treap[root].lc].size-1); }}void insert(int _i,int root){ treap[root].size++; treap[0].size = 0; if(treap[_i].value > treap[root].value){ if(treap[root].rc){ insert(_i,treap[root].rc); } else{ treap[root].rc = _i; treap[_i].fa = root; } } else{ if(treap[root].lc){ insert(_i,treap[root].lc); } else{ treap[root].lc = _i; treap[_i].fa = root; } }}void Rrot(int i,int j){ int k = treap[j].fa; treap[i].fa = treap[j].fa; if(treap[k].lc == j) treap[k].lc = i; else if(treap[k].rc == j) treap[k].rc = i; treap[j].lc = treap[i].rc; treap[treap[j].lc].fa = j; treap[i].rc = j; treap[j].fa = i; treap[j].size = treap[treap[j].lc].size + treap[treap[j].rc].size + 1; treap[i].size = treap[treap[i].lc].size + treap[treap[i].rc].size + 1;}void Lrot(int i,int j){ int k = treap[j].fa; treap[i].fa = treap[j].fa; if(treap[k].lc == j) treap[k].lc = i; else if(treap[k].rc == j) treap[k].rc = i; treap[j].rc = treap[i].lc; treap[treap[j].rc].fa = j; treap[i].lc = j; treap[j].fa = i; treap[j].size = treap[treap[j].lc].size + treap[treap[j].rc].size + 1; treap[i].size = treap[treap[i].lc].size + treap[treap[i].rc].size + 1;}void siftup(int i){ if(!i) return; int j = treap[i].fa; if(treap[i].priority > treap[j].priority){ if(treap[j].lc == i){ Rrot(i,j); siftup(i); } else if(treap[j].rc == i){ Lrot(i,j); siftup(i); } } return;}int main(){ memset(treap,0,sizeof(treap)); scanf("%d%d",&M,&N); treap[0].priority = INT_MAX; treap[0].value = INT_MIN; treap[0].size = 0; for(int i=1;i<=M;++i){ scanf("%d",&treap[i].value); treap[i].priority = rand(); } int mark; int i = 1; while(N--){ scanf("%d",&mark); for(;i<=mark;++i){ treap[i].size = 1; insert(i,treap[0].rc); siftup(i); } real_i++; Find2(treap[0].rc,real_i); } //system("pause"); return 0;}
0 0
- poj 1442 Black Box
- POJ 1442 Black Box
- poj--1442--black box
- POJ 1442 Black Box
- POJ 1442 Black Box
- POJ 1442 Black Box
- POJ 1442 Black Box
- poj 1442 Black Box
- POJ 1442 Black Box
- POJ 1442 Black Box
- POJ 1442 Black Box
- poj 1442 Black Box
- POJ 1442 Black Box
- poj 1442 Black Box
- poj 1442 Black Box
- POJ 1442 Black Box
- 【POJ 1442】 Black Box
- poj 1442 Black Box
- 写代码的最高境界----就是不写代码
- 深拷贝和浅拷贝的理解
- 排列(permutation):用1,2,3,...,9组成3个三位数abc, def和ghi,每个数字恰好使用一次,要求abc:def:ghi = 1:2:3。输出所有解。提示:不必太动脑筋。
- Struts2+Hibernate4整合(二)
- Android拖拽的ExpandableListView
- POJ 1442 Black Box
- 默认构造函数和默认复制构造函数
- JS正则表达式+---贪婪和非贪婪模式学习总结
- 关于VS2013中的字体颜色
- UI基础-UITableView 编辑
- 浅析AFNetWorking
- 安卓驱动、HAL、JNI与java
- UITableView 高级
- Integer Division