KunKun的征途

明天的明天,你还会送我水晶之恋吗?

导航

[hihoCoder1329] 带Split和Merge的Treap

Posted on 2016-07-17 11:18  西域小车  阅读(277)  评论(0)    收藏  举报

题目链接:http://hihocoder.com/problemset/problem/1329

这题本来是学Splay的题,但是我为了练习Treap的Split和Merge操作,就借来用一用。

就是砍树然后再合并。

存个代码:

 

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <vector>
  5 #include <map>
  6 #include <set>
  7 #include <string>
  8 #include <bitset>
  9 #include <cmath>
 10 #include <numeric>
 11 #include <iterator>
 12 #include <iostream>
 13 #include <cstdlib>
 14 #include <functional>
 15 #include <queue>
 16 #include <stack>
 17 #include <list>
 18 #include <ctime>
 19 using namespace std;
 20 
 21 const int inf = ~0U >> 1;
 22 
 23 typedef long long LL;
 24 
 25 struct TreapNode {
 26     int key, val, siz;
 27     TreapNode* ch[2];
 28     TreapNode() :val(0), siz(1){ key = rand(); ch[0] = ch[1] = NULL; }
 29     void rz(){
 30         siz = 1;
 31         if (ch[0]) siz += ch[0]->siz;
 32         if (ch[1]) siz += ch[1]->siz;
 33     }
 34     ~TreapNode(){
 35         if (ch[0]) delete ch[0];
 36         if (ch[1]) delete ch[1];
 37     }
 38 };
 39 
 40 typedef pair<TreapNode*, TreapNode*> DTreap;
 41 
 42 void rot(TreapNode*& rt, bool d){
 43     TreapNode* c = rt->ch[d];
 44     rt->ch[d] = c->ch[!d];
 45     c->ch[!d] = rt;
 46     rt->rz(); c->rz();
 47     rt = c;
 48 }
 49 
 50 void Insert(TreapNode*& rt, int val, int key = 0) {
 51     if (!rt){
 52         rt = new TreapNode();
 53         rt->val = val;
 54         if (key) rt->key = key;
 55         return;
 56     }
 57     //if (val == rt->val) return;
 58     bool d = val > rt->val;
 59     Insert(rt->ch[d], val, key);
 60     if (rt->ch[d]->key < rt->key) rot(rt, d);
 61     else rt->rz();
 62 }
 63 
 64 void Delete(TreapNode*& rt, int val) {
 65     if (rt == NULL) return;
 66     if (rt->val == val) {
 67         if (rt->ch[0] == NULL && rt->ch[1] == NULL) {
 68             delete rt;
 69             rt = NULL;
 70             return;
 71         }
 72         else if (rt->ch[0] == NULL) {
 73             rot(rt, 1);
 74             Delete(rt->ch[0], val);
 75         }
 76         else if (rt->ch[1] == NULL) {
 77             rot(rt, 0);
 78             Delete(rt->ch[1], val);
 79         }
 80         else {
 81             bool d = rt->ch[1]->key > rt->ch[0]->key;
 82             rot(rt, d);
 83             Delete(rt->ch[!d], val);
 84         }
 85     }
 86     else {
 87         bool d = val > rt->val;
 88         Delete(rt->ch[d], val);
 89     }
 90     rt->rz();
 91 }
 92 
 93 int Kth(TreapNode* rt, int k) {
 94     if (!rt) return -inf;
 95     if (rt->siz < k) return -inf;
 96     int r = 0;
 97     if (!rt->ch[0]) r = 0;
 98     else r = rt->ch[0]->siz;
 99     if (r == k - 1) return rt->val;
100     if (k - 1 < r) return Kth(rt->ch[0], k);
101     return Kth(rt->ch[1], k - r - 1);
102 }
103 
104 DTreap Split(TreapNode* rt, int val) {
105     DTreap ret;
106     Insert(rt, val, -inf);
107     ret.first = rt->ch[0];
108     ret.second = rt->ch[1];
109     rt->ch[0] = rt->ch[1] = NULL;
110     delete rt;
111     return ret;
112 }
113 
114 void Merge(DTreap dt, TreapNode*& rt) {
115     rt = NULL;
116     TreapNode* tch = dt.first?dt.first:dt.second;
117     if(tch) {
118         TreapNode* nd = new TreapNode();
119         nd->key = -inf;
120         nd->val = tch->val;
121         nd->ch[0] = dt.first;
122         nd->ch[1] = dt.second;
123         rt = nd;
124         Delete(rt, nd->val);
125     }
126 }
127 
128 int ans;
129 
130 void Query(TreapNode* rt, int x) {
131     if (rt == NULL) return;
132     if (rt->val == x) {
133         ans = x;
134         return;
135     }
136     if (rt->val > x) {
137         Query(rt->ch[0], x);
138     }
139     else {
140         ans = max(ans, rt->val);
141         Query(rt->ch[1], x);
142     }
143 }
144 
145 char cmd[2];
146 int a, b, n;
147 
148 int main() {
149     srand(time(NULL));
150     scanf("%d", &n);
151     TreapNode* root = NULL;
152     for (int i = 0; i < n; i++) {
153         scanf("%s", cmd);
154         if (cmd[0] == 'I') {
155             scanf("%d", &a);
156             Insert(root, a);
157         }
158         else if (cmd[0] == 'Q') {
159             ans = -inf;
160             scanf("%d", &a);
161             Query(root, a);
162             printf("%d\n", ans);
163         }
164         else {
165             scanf("%d%d", &a, &b);
166             DTreap dt = Split(root, a);
167             TreapNode* lch = dt.first;
168             TreapNode* rch = dt.second;
169             dt = Split(rch, b + 1);
170             if (dt.first) delete dt.first;
171             dt.first = lch;
172             Merge(dt, root);
173         }
174     }
175     if (root) delete root;
176     return 0;
177 }