Skip to content

Commit 731ac05

Browse files
authored
Create Persistent Treap.cpp
1 parent c9ac3fa commit 731ac05

File tree

1 file changed

+214
-0
lines changed

1 file changed

+214
-0
lines changed

Persistent Treap.cpp

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
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 rnd()
24+
{
25+
return (rand()<<15)|rand();
26+
}
27+
28+
struct Node
29+
{
30+
int key, pr, sz, cnt[4];
31+
Node *c[2];
32+
33+
Node(int k = 0)
34+
{
35+
key = k;
36+
pr = rnd();
37+
sz = 1;
38+
memset(cnt, 0, sizeof cnt);
39+
cnt[k] = 1;
40+
c[0] = c[1] = np;
41+
}
42+
};
43+
44+
Node *root[10000];
45+
46+
void delTreap(Node *&x)
47+
{
48+
if (x == np) return;
49+
delTreap(x->c[0]);
50+
delTreap(x->c[1]);
51+
delete x;
52+
}
53+
54+
inline int sz(Node *&x)
55+
{
56+
return (x == np) ? 0:x->sz;
57+
}
58+
59+
inline int cnt(Node *&x, int &i)
60+
{
61+
return (x == np) ? 0:x->cnt[i];
62+
}
63+
64+
int getv(char &c)
65+
{
66+
if (c == 'A') return 0;
67+
if (c == 'G') return 1;
68+
if (c == 'T') return 2;
69+
return 3;
70+
}
71+
72+
void upd(Node *&x)
73+
{
74+
if (x == np) return;
75+
x->sz = 1+sz(x->c[0])+sz(x->c[1]);
76+
77+
for (int t1 = 0; t1 < 4; ++t1)
78+
x->cnt[t1] = cnt(x->c[0],t1)+cnt(x->c[1],t1);
79+
80+
++x->cnt[x->key];
81+
}
82+
83+
void Split(Node *x, Node *&L, Node *&R, int i)
84+
{
85+
if (x == np)
86+
L = R = np;
87+
else
88+
{
89+
Node *cn = new Node;
90+
*cn = *x;
91+
92+
if (i <= sz(cn->c[0]))
93+
Split(cn->c[0], L, cn->c[0], i), R = cn;
94+
else
95+
Split(cn->c[1], cn->c[1], R, i-sz(cn->c[0])-1), L = cn;
96+
97+
upd(cn);
98+
}
99+
}
100+
101+
void Merge(Node *&x, Node *L, Node *R)
102+
{
103+
if (L == np || R == np)
104+
x = (L != np) ? L:R;
105+
else
106+
{
107+
Node *cn = new Node;
108+
109+
if (L->pr > R->pr)
110+
{
111+
*cn = *L;
112+
Merge(cn->c[1], cn->c[1], R);
113+
}
114+
else
115+
{
116+
*cn = *R;
117+
Merge(cn->c[0], L, cn->c[0]);
118+
}
119+
120+
x = cn;
121+
}
122+
123+
upd(x);
124+
}
125+
126+
void Cross(int id1, int id2, int k1, int k2, Node *&A, Node *&B)
127+
{
128+
Node *a, *b, *c, *d;
129+
Split(root[id1], a, b, k1+1);
130+
Split(root[id2], c, d, k2+1);
131+
Merge(A, a, d);
132+
Merge(B, c, b);
133+
}
134+
135+
void Mutate(Node *&root, int i, int v)
136+
{
137+
if (root == np) return;
138+
Node *cn = new Node;
139+
*cn = *root;
140+
root = cn;
141+
142+
if (i == sz(cn->c[0]))
143+
cn->key = v;
144+
else if (i < sz(cn->c[0]))
145+
Mutate(cn->c[0], i, v);
146+
else
147+
Mutate(cn->c[1], i-sz(cn->c[0])-1, v);
148+
149+
upd(cn);
150+
}
151+
152+
void Count(Node *x, int k1, int k2)
153+
{
154+
Node *t1, *t2;
155+
Split(x, x, t2, k2+1);
156+
Split(x, x, t1, k1);
157+
158+
for (int i = 0; i < 4; ++i)
159+
cout << cnt(t1,i) << ' ';
160+
cout << '\n';
161+
}
162+
163+
int main()
164+
{
165+
ios_base::sync_with_stdio(0);
166+
167+
168+
srand(time(0));
169+
int n, q, id1, id2, k1, k2;
170+
char m;
171+
string s;
172+
cin >> n;
173+
174+
for (int t1 = 0; t1 < n; ++t1)
175+
{
176+
root[t1] = np;
177+
cin >> s;
178+
179+
for (char &c: s)
180+
Merge(root[t1], root[t1], new Node(getv(c)));
181+
}
182+
183+
int cv = n-1; // current version
184+
cin >> q;
185+
186+
while (q)
187+
{
188+
--q;
189+
cin >> s;
190+
191+
if (s[1] == 'R')
192+
{
193+
cin >> id1 >> id2 >> k1 >> k2;
194+
Cross(id1-1, id2-1, k1-1, k2-1, root[cv+1], root[cv+2]);
195+
cv += 2;
196+
}
197+
else if (s[0] == 'M')
198+
{
199+
cin >> id1 >> k1 >> m;
200+
Mutate(root[id1-1], k1-1, getv(m));
201+
}
202+
else
203+
{
204+
cin >> id1 >> k1 >> k2;
205+
Count(root[id1-1], k1-1, k2-1);
206+
}
207+
}
208+
209+
210+
211+
212+
213+
return 0;
214+
}

0 commit comments

Comments
 (0)