poj 1442 Treap实现名次树

Treap的入门题目,每个结点多维护一个size表示以它为根的子树的结点数,然后查kth的时候一层一层向下即可。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cstdio>
 5 #include <ctime>
 6 using namespace std;
 7
 8 struct Node
 9 {
10     Node * ch[2];
11     int r;
12     int v;
13     int s;
14     int cmp( int x )
15     {
16         if ( x == v ) return -1;
17         return x < v ? 0 : 1;
18     }
19     void maintain()
20     {
21         s = 1;
22         if ( ch[0] != NULL ) s += ch[0]->s;
23         if ( ch[1] != NULL ) s += ch[1]->s;
24     }
25 };
26
27 void rotate( Node * & o, int d )
28 {
29     Node * k = o->ch[d ^ 1];
30     o->ch[d ^ 1] = k->ch[d];
31     k->ch[d] = o;
32     o->maintain();
33     k->maintain();
34     o = k;
35 }
36
37 void insert( Node * & o, int x )
38 {
39     if ( o == NULL )
40     {
41         o = new Node();
42         o->ch[0] = o->ch[1] = NULL;
43         o->v = x;
44         o->r = rand();
45         o->s = 1;
46     }
47     else
48     {
49         int d = ( x < o->v ? 0 : 1 );
50         insert( o->ch[d], x );
51         if ( o->ch[d]->r > o->r )
52         {
53             rotate( o, d ^ 1 );
54         }
55         o->maintain();
56     }
57 }
58
59 int kth( Node * o, int k )
60 {
61     int tmp = ( o->ch[0] == NULL ? 0 : o->ch[0]->s );
62     if ( k == tmp + 1 ) return o->v;
63     else if ( k < tmp + 1 ) return kth( o->ch[0], k );
64     else return kth( o->ch[1], k - tmp - 1 );
65 }
66
67 const int N = 30001;
68 int a[N];
69
70 int main ()
71 {
72     int n, m;
73     while ( scanf("%d%d", &n, &m) != EOF )
74     {
75         Node * root = NULL;
76         for ( int i = 1; i <= n; i++ )
77         {
78             scanf("%d", a + i);
79         }
80         int tt, cnt = 1;
81         for ( int i = 1; i <= m; i++ )
82         {
83             scanf("%d", &tt);
84             while ( cnt <= tt )
85             {
86                 insert( root, a[cnt++] );
87             }
88             printf("%d\n", kth( root, i ));
89         }
90     }
91     return 0;
92 }
时间: 2024-08-08 09:41:38

poj 1442 Treap实现名次树的相关文章

Black Box(POJ 1442&#183;TREAP实现)

传送门:http://poj.org/problem?id=1442 Black Box Time Limit: 1000MS   Memory Limit: 10000K       Description Our Black Box represents a primitive database. It can save an integer array and has a special i variable. At the initial moment Black Box is empt

Treap 实现名次树

在主流STL版本中,set,map,都是BST实现的,具体来说是一种称为红黑树的动态平衡BST: 但是在竞赛中并不常用,因为红黑树过于复杂,他的插入 5 种,删除 6 中,代码量极大(如果你要改板子的话): 相比之下有一种Treap的动态平衡BST,却也可以做到插入,删除,查找的期望时间复杂度O(logn): 结点定义: struct Node { Node *ch[2]; int r; //优先级 int v; //值 int s; //结点总数 Node(int v):v(v) { ch[0

Treap和名次树

Treap名字的来源:Tree+Heap,正如名字一样,就是一颗简单的BST,一坨堆的合体.BST的不平衡的根本原因在于基于左<=根<=右的模式吃单调序列时候会无脑成长链,而Treap则添加一个优先级属性,值的大小随机生成,用最大堆的方式维护.之所以使用堆,是因为堆是一颗 完全二叉树,而BST梦寐以求的就是完全二叉结构,二者一结合,就产生了一种新的Balanced BST.Treap依赖于随机数,随机生成的优先级属性,通过简单的左右旋可以将长链旋转成近似完全二叉树结构,注意只是近似,平均情况下

Treap实现名次树

Treap(树堆)的大部分功能STL的set都可以实现,但因为set的过度封装使得某些特定的功能不能实现,比如求第k大的值. Code: 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1000 + 10; 4 5 struct node { 6 node *ch[2]; 7 int r; 8 int v; 9 int s; 10 node (int v):v(v) {ch[0] = ch[1] = NUL

POJ 1442 treap

裸treap. 只需增加一个size记录其儿子个数便可找到第k大数. #include <cstdio> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <cstdlib> #include <cmath> #include <utility> #include <vector>

POJ 1442(treap || 优先队列)

treap套用模板即可: #include <iostream> #include <cstdio> #include <cstdlib> using namespace std; #define maxn 30000+5 int m,n; int a[maxn],b[maxn]; int val[maxn],ch[maxn][2],r[maxn],size[maxn],root,cnt,counts[maxn]; inline void pushup(int rt)

poj 1442 Black Box (treap树入门题)

1 /**************************************************** 2 题目: Black Box(poj 1442) 3 链接: http://poj.org/problem?id=1442 4 题意: 给n个数,m个询问,对第i数个询问前Xi个数中第 5 i小的是那个数. 6 算法: treap树 7 *****************************************************/ 8 #include<iostream

uvalive 5031 Graph and Queries 名次树+Treap

题意:给你个点m条边的无向图,每个节点都有一个整数权值.你的任务是执行一系列操作.操作分为3种... 思路:本题一点要逆向来做,正向每次如果删边,复杂度太高.逆向到一定顺序的时候添加一条边更容易.详见算法指南P235. 1 #include<cstdlib> 2 3 struct Node 4 { 5 Node *ch[2]; // 左右子树 6 int r; // 随机优先级 7 int v; // 值 8 int s; // 结点总数 9 Node(int v):v(v) 10 { 11

POJ 1442 Black Box treap求区间第k大

题目来源:POJ 1442 Black Box 题意:输入xi 输出前xi个数的第i大的数 思路:试了下自己的treap模版 #include <cstdio> #include <cstring> #include <cstdlib> #include <ctime> using namespace std; struct Node { Node *ch[2]; int r; int v; int s; Node(){} Node(int v): v(v)