Skip to content

Commit c9ac3fa

Browse files
authored
Create Implicit Treap.cpp
1 parent df0e206 commit c9ac3fa

File tree

1 file changed

+300
-0
lines changed

1 file changed

+300
-0
lines changed

Implicit Treap.cpp

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
4+
typedef unsigned short usint;
5+
typedef unsigned uint;
6+
typedef long lint;
7+
typedef short sint;
8+
typedef long double ld;
9+
typedef long long llint;
10+
typedef unsigned long ulint;
11+
typedef unsigned long long ullint;
12+
13+
#define INF (1<<30)
14+
#define MOD 1000000007
15+
#define mp make_pair
16+
#define mt make_tuple
17+
#define pii pair <int,int>
18+
#define pcc pair <char,char>
19+
#define pss pair <string,string>
20+
#define np nullptr
21+
22+
23+
inline int randNum()
24+
{
25+
return (rand()<<15)|rand();
26+
}
27+
28+
struct Node
29+
{
30+
int key, pr, sz, sum, lazy, minv;
31+
bool rev;
32+
Node *c[2];
33+
34+
Node(int k = 0, int p = randNum())
35+
{
36+
sum = minv = key = k;
37+
pr = p;
38+
sz = 1;
39+
rev = lazy = 0;
40+
c[0] = c[1] = np;
41+
}
42+
};
43+
44+
void deleteTreap(Node *root)
45+
{
46+
if (root == np) return;
47+
deleteTreap(root->c[0]);
48+
deleteTreap(root->c[1]);
49+
delete root;
50+
}
51+
52+
void pushDown(Node *&root)
53+
{
54+
if (root == np) return;
55+
56+
if (root->lazy)
57+
{
58+
root->key += root->lazy;
59+
root->sum += (root->sz * root->lazy);
60+
if (root->c[0] != np) root->c[0]->lazy += root->lazy;
61+
if (root->c[1] != np) root->c[1]->lazy += root->lazy;
62+
root->lazy = 0;
63+
}
64+
65+
if (root->rev)
66+
{
67+
root->rev = 0;
68+
swap(root->c[0], root->c[1]);
69+
if (root->c[0] != np) root->c[0]->rev ^= 1;
70+
if (root->c[1] != np) root->c[1]->rev ^= 1;
71+
}
72+
}
73+
74+
inline int getSum(Node *&root)
75+
{
76+
return (root == np) ? 0:root->sum;
77+
}
78+
79+
inline int getMinv(Node *&root)
80+
{
81+
return (root == np) ? INF:root->minv;
82+
}
83+
84+
void updateRange(Node *&root)
85+
{
86+
if (root == np) return;
87+
pushDown(root->c[0]);
88+
pushDown(root->c[1]);
89+
root->sum = root->key+getSum(root->c[0])+getSum(root->c[1]);
90+
root->minv = min(root->key, min(getMinv(root->c[0]),getMinv(root->c[1])));
91+
}
92+
93+
inline int getSz(Node *&root)
94+
{
95+
return (root == np) ? 0:root->sz;
96+
}
97+
98+
inline void updateSz(Node *&root)
99+
{
100+
if (root != np) root->sz = 1+getSz(root->c[0])+getSz(root->c[1]);
101+
}
102+
103+
void inOrder(Node *&root, Node *x)
104+
{
105+
if (x == np) return;
106+
pushDown(x);
107+
inOrder(root, x->c[0]);
108+
cout << x->key << ' ';
109+
inOrder(root, x->c[1]);
110+
updateRange(x);
111+
if (x == root) cout << '\n';
112+
}
113+
114+
void Split(Node *root, Node *&L, Node *&R, int i)
115+
{
116+
if (root == np) return void(L = R = np);
117+
pushDown(root);
118+
119+
if (i <= getSz(root->c[0]))
120+
// root->c[0] instead of R->c[0] because
121+
// R = root is after the next splitting
122+
Split(root->c[0], L, root->c[0], i), R = root;
123+
else
124+
Split(root->c[1], root->c[1], R, i-getSz(root->c[0])-1), L = root;
125+
126+
updateSz(root);
127+
updateRange(root);
128+
}
129+
130+
void Merge(Node *&root, Node *L, Node *R)
131+
{
132+
pushDown(L);
133+
pushDown(R);
134+
135+
if (L == np || R == np)
136+
root = (L != np) ? L:R;
137+
else if (L->pr > R->pr)
138+
Merge(L->c[1], L->c[1], R), root = L;
139+
else
140+
Merge(R->c[0], L, R->c[0]), root = R;
141+
142+
updateSz(root);
143+
updateRange(root);
144+
}
145+
146+
void Insert(Node *&root, Node *x, int &i)
147+
{
148+
if (i < 0 || (root != np && i > root->sz)) return;
149+
Node *L, *R;
150+
Split(root, L, R, i);
151+
Merge(root, L, x);
152+
Merge(root, root, R);
153+
}
154+
155+
void Delete(Node *&root, int &i)
156+
{
157+
if (root == np || i < 0 || i >= root->sz) return;
158+
Node *t1, *t2, *t3;
159+
Split(root, t1, t2, i);
160+
Split(t2, t2, t3, 1);
161+
Merge(root, t1, t3);
162+
delete t2;
163+
}
164+
165+
void Reverse(Node *&root, int &L, int &R)
166+
{
167+
if (root == np) return;
168+
Node *t1, *t2, *t3;
169+
Split(root, t1, t3, R+1);
170+
Split(t1, t1, t2, L);
171+
if (t2 != np) t2->rev ^= 1;
172+
Merge(t2, t2, t3);
173+
Merge(root, t1, t2);
174+
}
175+
176+
void circularShift(Node *&root, int &L, int &R, int &t)
177+
{
178+
if (root == np) return;
179+
t %= (R-L+1);
180+
if (!t || L==R) return;
181+
Node *t1, *t2, *t3, *t4;
182+
Split(root, t1, t4, R+1);
183+
Split(t1, t1, t2, L);
184+
Split(t2, t2, t3, R-L+1-t);
185+
Merge(t2, t2, t4);
186+
Merge(t1, t1, t3);
187+
Merge(root, t1, t2);
188+
}
189+
190+
void Add(Node *&root, int &L, int &R, int &v)
191+
{
192+
if (root == np) return;
193+
Node *t1, *t2, *t3;
194+
Split(root, t1, t3, R+1);
195+
Split(t1, t1, t2, L);
196+
if (t2 != np) t2->lazy += v;
197+
Merge(t2, t2, t3);
198+
Merge(root, t1, t2);
199+
}
200+
201+
int sumQuery(Node *&root, int &L, int &R)
202+
{
203+
if (root == np) return 0;
204+
Node *t1, *t2, *t3;
205+
Split(root, t1, t3, R+1);
206+
Split(t1, t1, t2, L);
207+
int ans = 0;
208+
if (t2 != np) ans = t2->sum;
209+
Merge(t2, t2, t3);
210+
Merge(root, t1, t2);
211+
return ans;
212+
}
213+
214+
int minQuery(Node *&root, int &L, int &R)
215+
{
216+
if (root == np) return INF;
217+
Node *t1, *t2, *t3;
218+
Split(root, t1, t3, R+1);
219+
Split(t1, t1, t2, L);
220+
int ans = INF;
221+
if (t2 != np) ans = t2->minv;
222+
Merge(t2, t2, t3);
223+
Merge(root, t1, t2);
224+
return ans;
225+
}
226+
227+
int main()
228+
{
229+
ios_base::sync_with_stdio(0);
230+
231+
232+
int q;
233+
cin >> q;
234+
srand(time(0));
235+
Node *root = np;
236+
237+
while (q)
238+
{
239+
string c;
240+
cin >> c;
241+
242+
if (c[0] == 'i')
243+
{
244+
int x, i;
245+
cin >> x >> i;
246+
Insert(root, new Node(x), i);
247+
}
248+
else if (c[0] == 'm' && c[1] == 'e')
249+
{
250+
int x;
251+
cin >> x;
252+
Merge(root, root, new Node(x));
253+
}
254+
else if (c[0] == 'd')
255+
{
256+
int i;
257+
cin >> i;
258+
Delete(root, i);
259+
}
260+
else if (c[0] == 'r')
261+
{
262+
int L, R;
263+
cin >> L >> R;
264+
Reverse(root, L, R);
265+
}
266+
else if (c[0] == 'c')
267+
{
268+
int L, R, t;
269+
cin >> L >> R >> t;
270+
circularShift(root, L, R, t);
271+
}
272+
else if (c[0] == 'a')
273+
{
274+
int L, R, v;
275+
cin >> L >> R >> v;
276+
Add(root, L, R, v);
277+
}
278+
else if (c[0] == 's')
279+
{
280+
int L, R;
281+
cin >> L >> R;
282+
cout << sumQuery(root, L, R) << '\n';
283+
}
284+
else if (c[0] == 'm')
285+
{
286+
int L, R;
287+
cin >> L >> R;
288+
cout << minQuery(root, L, R) << '\n';
289+
}
290+
291+
inOrder(root,root);
292+
--q;
293+
}
294+
295+
deleteTreap(root);
296+
root = np;
297+
298+
299+
return 0;
300+
}

0 commit comments

Comments
 (0)