P3369 [TEMPLATE] Normal Balance Tree (Treap/SBT), p31_treap
Description
You need to write a data structure (refer to the title of the question) to maintain the number. The following operations are required:
Input/Output Format
Input Format:
The first behavior n indicates the number of operations. Each row in the n rows below has two numbers opt and x, and opt indicates the number of operations (1 <= opt <= 6)
Output Format:
For operations 3, 4, 5, 6, each row outputs a number, indicating the corresponding answer
Input and Output sample input sample #1:
101 1064654 11 3177211 4609291 6449851 841851 898516 819681 4927375 493598
Output sample #1:
10646584185492737
Description
Time-Space limit: 1000 ms, 128 M
1. Data range of n: n <= 100000
2. Data range of each number: [-1e7, 1e7]
Source: Tyvj1728 Formerly known as: normal Balance Tree
Thank you here
FHQ Treap...
This is one of the most amazing data structures I have ever seen !.
It can simulate all BST operations with two simple non-rotation operations.
Unbelievable.
If you are free, write a blog about this.
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <cmath> 5 # include <algorithm> 6 # include <cstdlib> 7 # include <ctime> 8 using namespace std; 9 const int MAXN = 100001; 10 static void read (int & n) 11 {12 char c = '+'; int x = 0; bool flag = 0; 13 while (c <'0' | c> '9') {c = getchar (); if (c = '-') flag = 1 ;} 14 while (c> = '0' & c <= '9') {x = (x <1) + (x <3) + (c-48 ); c = getchar ();} 15 flag = 1? N =-x: n = x; 16} 17 int ch [MAXN] [3]; // 0 left child 1 right child 18 int val [MAXN]; // The weight of each vertex 19 int pri [MAXN]; // The randomly generated attachment weight 20 int siz [MAXN]; // number of nodes in the I-node tree 21 int sz; // Number of summarized points 22 void update (int x) 23 {24 siz [x] = 1 + siz [ch [x] [0] + siz [ch [x] [1]; 25} 26 int new_node (int v) 27 {28 siz [++ sz] = 1; // a new node 29 val [sz] = v; 30 pri [sz] = rand (); 31 return sz; 32} 33 int merge (int x, int y) // merge 34 {35 if (! X |! Y) return x + y; // x and y must have a value of 0 36 if (pri [x] <pri [y]). // Add x to the tree on the left 37 {38 ch [x] [1] = merge (ch [x] [1], y ); // see GIF figure 39 update (x); 40 return x; 41} 42 else 43 {44 ch [y] [0] = merge (x, ch [y] [0]); 45 update (y); 46 return y; 47} 48} 49 void split (int now, int k, int & x, int & y) 50 {51 if (! Now) x = y = 0; // reach the leaf node 52 else 53 {54 if (val [now] <= k) // detach the right subtree 55 x = now, split (ch [now] [1], k, ch [now] [1], y); 56 else 57 y = now, split (ch [now] [0], k, x, ch [now] [0]); 58 update (now); 59} 60} 61 int kth (int now, int k) // query rank 62 {63 while (1) 64 {65 if (k <= siz [ch [now] [0]) 66 now = ch [now] [0]; // In the left subtree, and the number is smaller than the size of the Left subtree, iterative search for 67 else if (k = siz [ch [now] [0] + 1) 68 return now; // 69 else 70 k-= siz [ch [now] [0] + 1, now = ch [now] [1] is found; // go to the right subtree to find 71} 72} 73 int main () 74 {75 srand (unsigned) time (NULL); 76 int n; 77 read (n ); 78 int root = 0, x, y, z; 79 for (int I = 1; I <= n; I ++) 80 {81 int how,; 82 read (how); read (a); 83 if (how = 1) // insert 84 {85 split (root, a, x, y ); 86 root = merge (x, new_node (a), y); 87} 88 else if (how = 2) // Delete x 89 {90 split (root, a, x, z); 91 split (x, A-1, x, y); 92 y = merge (ch [y] [0], ch [y] [1]); 93 root = merge (x, y), z); 94} 95 else if (how = 3) // query the top 96 {97 split (root, A-1, x, y) of x; 98 printf ("% d \ n", siz [x] + 1 ); 99 root = merge (x, y); 100} 101 else if (how = 4) // query the number of x ranked by 102 {103 printf ("% d \ n", val [kth (root, a)]); 104} 105 else if (how = 5) // evaluate the x precursor 106 {107 split (root, A-1, x, y ); 108 printf ("% d \ n", val [kth (x, siz [x]); 109 root = merge (x, y ); 110} 111 else if (how = 6) // calculate the successor 112 of x {113 split (root, a, x, y ); 114 printf ("% d \ n", val [kth (y, 1)]); 115 root = merge (x, y); 116} 117} 118 return 0; 119}