Reprinted please indicate the source, thank you http://blog.csdn.net/acm_cxlove/article/details/7854526
By --- cxlove
Question: maintain a set, insert, and delete operations. After each step ends, the median is output.
Http://acm.zju.edu.cn/onlinejudge/showProblem.do? Problemid = 4736
Actually, we can solve this problem by thinking about the line segment tree. We need to discretization it,
The result is silly, and I think there are duplicates. In fact, you only need to record a few of them.
Then we use the Balance Tree and SBT to solve it.
# Include <iostream> # include <cstdio> # include <map> # include <cstring> # include <cmath> # include <vector> # include <queue> # include <algorithm> # include <set> # include <string> # define INF 1 <30 # define n 100005 # define maxn 100005 # define min (, b) (a) <(B )? (A) :( B) # define max (A, B) (a)> (B )? (A) :( B) # define Pb (a) push_back (a) # define MEM (a, B) memset (a, B, sizeof ()) # define EPS 1e-9 # define zero (a) FABS (a) <EPS # define ll long # define ull unsigned long # define lson (Step <1) # define rson (Step <1 | 1) # define mod 1000000007 # define MP (a, B) make_pair (a, B) using namespace STD; struct SBT {// left subtree pointer, right subtree pointer, size, key value int left, right, size; ll key; void Init () {left = right = Key = 0; size = 1 ;}t [N]; int Ro OT, TOT; // The root position and number of nodes // void left_rot (Int & X) {int K = T [X]. right; t [X]. right = T [K]. left; t [K]. left = x; t [K]. size = T [X]. size; t [X]. size = T [T [X]. left]. size + T [T [X]. right]. size + 1; X = K;} // right rotation void right_rot (Int & X) {int K = T [X]. left; t [X]. left = T [K]. right; t [K]. right = x; t [K]. size = T [X]. size; t [X]. size = T [T [X]. left]. size + T [T [X]. right]. size + 1; X = K;} // adjust the processing void maintain (Int & R, bool flag) {If (FLAG) {// update the right subtree if (T [T [T [R]. right ]. Right]. size> T [T [R]. left]. size) left_rot (r); else if (T [T [R]. right]. left]. size> T [T [R]. left]. size) {right_rot (T [R]. right); left_rot (r);} elsereturn;} else {// update in the left subtree if (T [T [T [R]. left]. left]. size> T [T [R]. right]. size) right_rot (r); else if (T [T [R]. left]. right]. size> T [T [R]. right]. size) {left_rot (T [R]. left); right_rot (r);} else return;} // update the subtree, and then update the root until the balance ends maintain (T [R]. left, false); maintain (T [R]. right, true); Maint Ain (R, false); maintain (R, true) ;}// Insert a new node void insert (Int & R, ll K) {If (r = 0) {r = ++ tot; t [R]. init (); t [R]. key = K;} else {T [R]. size ++; If (k <t [R]. key) insert (T [R]. left, k); elseinsert (T [R]. right, k); // adjust the value after insertion to ensure the balance of maintain (R, k> = T [R]. key) ;}} // Delete the node. Replace ll remove (Int & R, ll K) {int d_key; If (! R) return 0; t [R]. size --; // The former indicates the node to be deleted, and the latter indicates that this node does not exist if (T [R]. key = k | (T [R]. left = 0 & K <t [R]. key) | (T [R]. right = 0 & K> T [R]. key) {d_key = T [R]. key; If (T [R]. left & T [R]. right) T [R]. key = remove (T [R]. left, k + 1); elser = T [R]. left + T [R]. right; return d_key;} else return remove (k <t [R]. key? T [R]. left: T [R]. right, k);} // obtain the maximum number of k ll get_max_kth (Int & R, ll K) {int T = T [T [R]. right]. size + 1; if (t = k) return T [R]. key; If (T <k) return get_max_kth (T [R]. left, K-T); else return get_max_kth (T [R]. right, k);} // check whether the int find (Int & R, ll K) {If (! R) return 0; If (T [R]. key = k) return 1; if (k <t [R]. key) return find (T [R]. left, k); else return find (T [R]. right, k) ;}int main () {int t, q; scanf ("% d", & T); While (t --) {scanf ("% d ", & Q); Tot = root = 0; int CNT = 0; ll K; char STR [10]; while (Q --) {scanf ("% S % LLD ", STR, & K); If (STR [0] = 'A') {insert (root, k); CNT ++; If (CNT & 1) printf ("% LLD \ n", get_max_kth (root, CNT/2 + 1); else {ll ans = (LL) get_max_kth (root, CNT/2) + (LL) get_max_kth (root, CNT/2 + 1 ); If (ANS & 1) printf ("%. 1f \ n ", ANS/2.0); else printf (" % LLD \ n ", ANS/2) ;}} else {If (! Find (root, k) {printf ("wrong! \ N "); continue;} CNT --; remove (root, k); If (CNT = 0) {printf (" empty! \ N "); continue;} If (CNT & 1) printf (" % LLD \ n ", get_max_kth (root, CNT/2 + 1 )); else {ll ans = (LL) get_max_kth (root, CNT/2) + (LL) get_max_kth (root, CNT/2 + 1); If (ANS & 1) printf ("%. 1f \ n ", ANS/2.0); else printf (" % LLD \ n ", ANS/2) ;}}} return 0 ;}