Skip to content

Commit 90a92f4

Browse files
authored
Create Wavelet Tree.cpp
1 parent 595a5c1 commit 90a92f4

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

Wavelet Tree.cpp

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
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 all(c) c.begin(),c.end()
21+
#define ms(name,val) memset(name, val, sizeof name)
22+
#define np nullptr
23+
24+
25+
int A[100001];
26+
27+
struct Node
28+
{
29+
int mn, mx;
30+
vector <int> B;
31+
Node *c[2];
32+
33+
Node(int _mn = INT_MAX, int _mx = INT_MIN)
34+
{
35+
mn = _mn;
36+
mx = _mx;
37+
c[0] = c[1] = np;
38+
}
39+
};
40+
41+
void delTree(Node *&x)
42+
{
43+
if (x == np) return;
44+
delTree(x->c[0]);
45+
delTree(x->c[1]);
46+
delete x;
47+
}
48+
49+
inline void upd(Node *&x, int &v)
50+
{
51+
if (x == np) return;
52+
x->mn = min(x->mn,v);
53+
x->mx = max(x->mx,v);
54+
}
55+
56+
void Build(Node *&x, int *from, int *to)
57+
{
58+
if (x->mn == x->mx || from >= to) return;
59+
x->B.push_back(0);
60+
int mid = (x->mn+x->mx)>>1;
61+
Node *L = new Node, *R = new Node;
62+
auto f = [mid](int &x) { return (x <= mid); };
63+
64+
for (auto it = from; it != to; ++it)
65+
{
66+
x->B.push_back(x->B.back()+f(*it));
67+
if (*it <= mid) upd(L,*it); else upd(R,*it);
68+
}
69+
70+
auto pivot = stable_partition(from, to, f);
71+
x->c[0] = L, x->c[1] = R;
72+
Build(x->c[0], from, pivot);
73+
Build(x->c[1], pivot, to);
74+
if (L->mn == INT_MAX) x->c[0] = np, delete L;
75+
if (R->mn == INT_MAX) x->c[1] = np, delete R;
76+
}
77+
78+
int Frequency(Node *x, int L, int R, int &v) // return frequency of number 'v' in range [L,R]
79+
{
80+
while (x != np)
81+
{
82+
if (v < x->mn || v > x->mx) return 0;
83+
if (x->mn == x->mx) return R-L;
84+
int mid = (x->mn+x->mx)>>1;
85+
86+
if (v <= mid)
87+
L = x->B[L], R = x->B[R], x = x->c[0];
88+
else
89+
L -= x->B[L], R -= x->B[R], x = x->c[1];
90+
}
91+
92+
return 0;
93+
}
94+
95+
int LTE(Node *x, int L, int R, int &v) // returns count of numbers less than or equal to 'v' in range [L,R]
96+
{
97+
if (L > R || v < x->mn) return 0;
98+
if (x->mx <= v) return R-L;
99+
return LTE(x->c[0], x->B[L], x->B[R], v)+LTE(x->c[1], L-x->B[L], R-x->B[R], v);
100+
}
101+
102+
int Kth(Node *x, int L, int R, int k) // returns k-th number in range [L,R], aka k-th order statistic
103+
{
104+
if (L > R) return 0;
105+
if (x->mn == x->mx) return x->mn;
106+
int cntLeft = x->B[R]-x->B[L];
107+
if (k <= cntLeft) return Kth(x->c[0], x->B[L], x->B[R], k);
108+
return Kth(x->c[1], L-x->B[L], R-x->B[R], k-cntLeft);
109+
}
110+
111+
int main()
112+
{
113+
ios_base::sync_with_stdio(0);
114+
115+
116+
int n, q;
117+
cin >> n;
118+
Node *root = new Node;
119+
120+
for (int t1 = 1; t1 <= n; ++t1)
121+
{
122+
cin >> A[t1];
123+
upd(root,A[t1]);
124+
}
125+
126+
Build(root, A+1, A+n+1);
127+
cin >> q;
128+
129+
while (q)
130+
{
131+
--q;
132+
char c;
133+
int L, R, v;
134+
cin >> c;
135+
136+
if (c == 'F')
137+
{
138+
cin >> v >> L >> R;
139+
cout << Frequency(root, L-1, R, v) << '\n';
140+
}
141+
else if (c == 'L')
142+
{
143+
cin >> v >> L >> R;
144+
cout << LTE(root, L-1, R, v) << '\n';
145+
}
146+
else if (c == 'K')
147+
{
148+
cin >> v >> L >> R;
149+
cout << Kth(root, L-1, R, v) << '\n';
150+
}
151+
}
152+
153+
delTree(root), root = np;
154+
155+
156+
return 0;
157+
}

0 commit comments

Comments
 (0)