首页 > 代码库 > 好久不见的博客咯!——没有可持久化的可持久化treap
好久不见的博客咯!——没有可持久化的可持久化treap
每每想要去了解可持久化treap这个好写好调的东东,然后就发现网上只有一个人的——SymenYang的!在此我必须得把他批判一番——写方法不贴代码是什么心态!而且写出来的是有问题的呀!害人不浅!
好吧说正经事,这个版本的treap名叫可持久化treap却没有可持久化,而是借鉴了可持久化treap中的一些写法。貌似可持久化之后反而难写难调。。。在这个版本的treap中加入了堆权值来维护树的形状,然后由三种操作——合并(merge),按size拆分(split_size),按值拆分(split_kth)。先说说merge。merge 这个操作是将两颗子树a,b(b中元素大于等于a中的元素)合并。这是我们这就是一个递归的过程:对于a,b中的当前节点x,y,按照他们的堆权值来确定父亲和儿子的关系,然后再往下递归这个过程,接左儿子还是右儿子看具体的值。然后split中要引入一个nodepair的结构来返回(把一棵拆成两棵得要个结构来返回啊),基本的操作跟在bst上找第k大和前k个的值一致。。具体看代码理解吧。。。 不好画图。。。。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | /* 针对的是平衡二叉树那道入门题 */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 200001; int ans = 0; struct node{ int key,data,size; node *son[2]; node(){ key = rand();} }e[maxn],*root; int ne = 0; struct nodepair{ node* l,*r; }; nodepair mkpair(node* a,node* b){ nodepair x; x.l = a, x.r = b; return x; } void update(node* x){ if (x){ //判断不能少! x->size = 1; if (x->son[0]) x->size += x->son[0]->size; if (x->son[1]) x->size += x->son[1]->size; } } node* merge(node* a,node *b){ if (!a) {update(b); return b;} if (!b) {update(a); return a;} if (a->key <= b->key){ a->son[1] = merge(a->son[1],b); update(a); return a; } else { b->son[0] = merge(a,b->son[0]); update(b); return b; } } nodepair split_size(node* a, int k){ if (!a) return mkpair(NULL,NULL); if (!k) return mkpair(NULL,a); int ts = a->son[0] ? a->son[0]->size : 0; nodepair km; if (ts >= k){ km = split_size(a->son[0],k); a->son[0] = km.r; update(a); return mkpair(km.l,a); } else { km = split_size(a->son[1],k - ts - 1); a->son[1] = km.l; update(a); return mkpair(a,km.r); } } nodepair split_kth(node* a, int k){ if (!a) return mkpair(NULL,NULL); nodepair km; if (a->data <= k){ km = split_kth(a->son[1],k); a->son[1] = km.l; update(a); return mkpair(a,km.r); } else { km = split_kth(a->son[0],k); a->son[0] = km.r; update(a); return mkpair(km.l,a); } } node* insert( int v){ node* now = e + ne++; now->data = http://www.mamicode.com/v; nodepair km = split_kth(root,v); return merge(km.l,merge(now,km.r)); } node* del( int v){ nodepair km1 = split_kth(root,v-1); nodepair km2 = split_size(km1.r,1); return merge(km1.l,km2.r); } void askkth( int k){ node* now = root; while ( true ){ int ts = now->son[0] ? now->son[0]->size : 0; if (ts + 1 == k) break ; else { if (ts >= k) now = now->son[0]; else k -= ts + 1, now = now->son[1]; } } ans = now -> data; } node* askx( int v){ nodepair km = split_kth(root,v-1); ans = km.l ? km.l->size+1 : 1; return merge(km.l,km.r); } node* pre( int v){ nodepair km1 = split_kth(root,v-1); nodepair km2 = split_size(km1.l,km1.l->size - 1); ans = km2.r -> data; return merge(merge(km2.l,km2.r),km1.r); } node* sub( int v){ nodepair km1 = split_kth(root,v); nodepair km2 = split_size(km1.r,1); ans = km2.l -> data; return merge(km1.l,merge(km2.l,km2.r)); } int n; void read(){ scanf( "%d" ,&n); while (n--){ int tmp,op; scanf( "%d%d" ,&tmp,&op); if (tmp == 1) root = insert(op); if (tmp == 2) root = del(op); if (tmp == 3) root = askx(op); if (tmp == 4) askkth(op); if (tmp == 5) root = pre(op); if (tmp == 6) root = sub(op); if (tmp == 3 || tmp == 4 || tmp == 5 || tmp == 6) printf( "%d\n" ,ans); } } int main(){ read(); return 0; } |
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。