Test instructions: (Does the bare question still use me to say?)
Method: (The bare question also uses me to say?)
Analysis: The first time to write Treap is still a little bit harder, especially when you understand.
First, define the following
struct data
{
int L, R, V, Rnd, size, w;
};
Data tr[100001];
int n, ans, size, root;
void update (int k)
{
tr[k].size = tr[tr[k].l].size + tr[tr[k].r].size + tr[k].w;
}
void Lturn (int &k)
{
int t = TR[K].R;
TR[K].R = TR[T].L;
TR[T].L = k;
Tr[t].size = tr[k].size;
Update (k);
k = t;
}
void Rturn (int &k)
{
int t = TR[K].L;
TR[K].L = TR[T].R;
TR[T].R = k;
Tr[t].size = tr[k].size;
Update (k);
k = t;
}
Left-right spin as long as you draw two diagram, according to the picture to write, remember 6 lines of code (6 sentences) will not be wrong.
Second: Insert code
void Insert (int &k, int x)
{
if (k = = 0)
{
size + +;
k = size;
Tr[k].size = TR[K].W = 1;
TR[K].V = x;
Tr[k].rnd = rand ();
return;
}
Tr[k].size + +;
if (tr[k].v = = x) TR[K].W + +;
else if (x > Tr[k].v)
{
Insert (TR[K].R, x);
if (Tr[tr[k].r].rnd < Tr[k].rnd) Lturn (k);
} else
{
Insert (TR[K].L, x);
if (Tr[tr[k].l].rnd < Tr[k].rnd) Rturn (k);
}
}
1. The case of no nodes is discussed first
2. Discuss the inserted node exactly on the K
3. The relationship between the value of the inserted node and the value of K is discussed, if it is larger than the right subtree, the other is inserted into the left sub-tree. At the same time to maintain the characteristics of small Gan.
Delete a function
void del (int &k, int x)
{
if (k = = 0) return;
if (tr[k].v = = x)
{
if (tr[k].w > 1)
{
TR[K].W--, tr[k].size--;
return;
}
if (TR[K].L * TR[K].R = = 0) k = tr[k].l + tr[k].r;
else if (Tr[tr[k].l].rnd < tr[tr[k].r].rnd)
{
Rturn (k);
Del (k, x);
} else
{
Lturn (k);
Del (k, x);
}
} else if (x > Tr[k].v)
{
tr[k].size--;
Del (TR[K].R, x);
} else
{
tr[k].size--;
Del (TR[K].L, x);
}
}
1. Discussion no nodes are not deleted
2. If it happens to be at K
More than 1 at 1.K is deleted directly
There is only one child node at 2.K, the node replaces the K
3. If the left Rnd is less than the right Rnd, turn right, and the root node is removed at the leaf node
4. In contrast to (3), the left-to-leaf node is deleted
3. If the value of K is greater than the size--, then the right subtree is deleted.
4. If the value of K is smaller than the K size--, then the left subtree is deleted.
Ranking of query X
int Query_rank (int k, int x)
{
if (k = = 0) return 0;
if (tr[k].v = = x) return tr[tr[k].l].size + 1;
else if (x > Tr[k].v)
{
return tr[tr[k].l].size + TR[K].W + query_rank (TR[K].R, x);
} else return Query_rank (TR[K].L, x);
}
1. Discussion of the absence of nodes
2. If it happens to be at K, the number of nodes directly returning to the left subtree plus 1
3. Returns the number of nodes in the left subtree plus K points plus a recursive query to the right subtree if it is larger than the value of K
4. Returns the recursive query of the left subtree if it is smaller than the value at K
Number of queries ranked as X
int query_num (int k, int x)
{
if (k = = 0) return 0;
if (x <= tr[tr[k].l].size)
{
return query_num (TR[K].L, x);
} else if (x > tr[tr[k].l].size + tr[k].w)
{
return query_num (TR[K].R, X-TR[TR[K].L].SIZE-TR[K].W);
}else
{
return tr[k].v;
}
}
1. Discussion of the absence of nodes
2. If x is less than or equal to the number of nodes in the left subtree returns the recursive query for the left subtree
3. If x is larger than the number of nodes in the Zuozi plus the number of nodes k the recursive query of the number of X-left dial hand tree nodes in the right subtree is returned
4. In addition to 2.3, it must be the number of K, return the value at K
Seeking precursors
void Query_pro (int k, int x)
{
if (k = = 0) return;
if (TR[K].V < x)
{
ans = k;
Query_pro (TR[K].R, x);
} else Query_pro (TR[K].L, x);
}
1. Discussion of the absence of nodes
2. If x is larger than K, use ans to record k, then two to right subtree
3. Contrary to 2, two points to Zuozi
Seeking Successors
void Query_sub (int k, int x)
{
if (k = = 0) return;
if (tr[k].v > x)
{
ans = k;
Query_sub (TR[K].L, x);
} else Query_sub (TR[K].R, x);
}
1. Discussion of the absence of nodes
2. If x is smaller than the K value, use ans to record k and then two points to Zuozi
3. In contrast to 2, two points to the right sub-tree
The main function (the goods are completely to the word)
int main ()
{
scanf ("%d", &n);
int opt, x;
for (int i = 1; I <= n; i++)
{
scanf ("%d%d", &opt, &x);
Switch (opt)
{case
1:insert (root, x);
Case 2:d El (root, x);
Case 3:p rintf ("%d\n", Query_rank (root, x));
Case 4:p rintf ("%d\n", Query_num (root, x));
Case 5:ans = 0;query_pro (root, x);p rintf ("%d\n", TR[ANS].V);
Case 6:ans = 0;query_sub (root, x);p rintf ("%d\n", tr[ans].v);