Skip to content

Commit 4dc1162

Browse files
committed
LibreOJ: 106
二逼平衡树
1 parent 03523d6 commit 4dc1162

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed

LibreOJ/106.cpp

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/**
2+
* @file 106.cpp
3+
* @author Macesuted ([email protected])
4+
* @date 2023-03-02
5+
*
6+
* @copyright Copyright (c) 2023
7+
*
8+
*/
9+
10+
#include <bits/stdc++.h>
11+
using namespace std;
12+
13+
#ifndef LOCAL
14+
#define endl '\n'
15+
#endif
16+
17+
bool mem1;
18+
19+
#define maxn 50005
20+
21+
mt19937 rnd(20080618);
22+
23+
class FhqTreap {
24+
private:
25+
struct Node {
26+
Node *l, *r;
27+
int rnk, siz, val;
28+
Node(int _val) { l = r = nullptr, rnk = rnd(), siz = 1, val = _val; }
29+
};
30+
31+
Node* root;
32+
33+
int getSiz(Node* p) { return p ? p->siz : 0; }
34+
void pushUp(Node* p) { return p->siz = getSiz(p->l) + getSiz(p->r) + 1, void(); }
35+
void split(Node* p, Node*& t1, Node*& t2, int v) {
36+
if (!p) return t1 = t2 = nullptr, void();
37+
if (p->val < v)
38+
t1 = p, split(p->r, t1->r, t2, v);
39+
else
40+
t2 = p, split(p->l, t1, t2->l, v);
41+
return pushUp(p);
42+
}
43+
void merge(Node*& p, Node* t1, Node* t2) {
44+
if (!t1) return p = t2, void();
45+
if (!t2) return p = t1, void();
46+
if (t1->rnk < t2->rnk)
47+
p = t1, merge(p->r, t1->r, t2);
48+
else
49+
p = t2, merge(p->l, t1, t2->l);
50+
return pushUp(p);
51+
}
52+
53+
public:
54+
FhqTreap(void) { root = nullptr; }
55+
void insert(int v) {
56+
Node* tr = nullptr;
57+
split(root, root, tr, v);
58+
return merge(root, root, new Node(v)), merge(root, root, tr);
59+
}
60+
void erase(int v) {
61+
Node *tp = nullptr, *tr = nullptr;
62+
split(root, root, tp, v), split(tp, tp, tr, v + 1);
63+
return delete tp, merge(root, root, tr);
64+
}
65+
int query(int l, int r) {
66+
Node *tp = nullptr, *tr = nullptr;
67+
split(root, root, tp, l), split(tp, tp, tr, r + 1);
68+
int ret = getSiz(tp);
69+
return merge(root, root, tp), merge(root, root, tr), ret;
70+
}
71+
};
72+
class SegmentTree {
73+
private:
74+
struct Node {
75+
Node *l, *r;
76+
FhqTreap FT;
77+
Node(void) { l = r = nullptr; }
78+
};
79+
80+
Node* root;
81+
82+
void update(Node*& p, int l, int r, int v, int w) {
83+
if (!p) p = new Node();
84+
w > 0 ? p->FT.insert(w) : p->FT.erase(-w);
85+
if (l == r) return;
86+
int mid = (l + r) >> 1;
87+
v <= mid ? update(p->l, l, mid, v, w) : update(p->r, mid + 1, r, v, w);
88+
}
89+
int query(Node*& p, int l, int r) { return p ? p->FT.query(l, r) : 0; }
90+
int query1(Node*& p, int l, int r, int v, int ql, int qr) {
91+
if (!p) return 0;
92+
if (v >= r) return query(p, ql, qr);
93+
int mid = (l + r) >> 1;
94+
return v <= mid ? query1(p->l, l, mid, v, ql, qr) : query(p->l, ql, qr) + query1(p->r, mid + 1, r, v, ql, qr);
95+
}
96+
int query2(Node*& p, int l, int r, int v, int ql, int qr) {
97+
if (l == r) return l;
98+
int mid = (l + r) >> 1, vl = query(p->l, ql, qr);
99+
return vl >= v ? query2(p->l, l, mid, v, ql, qr) : query2(p->r, mid + 1, r, v - vl, ql, qr);
100+
}
101+
int query4(Node*& p, int l, int r, int v, int ql, int qr) {
102+
if (!query(p, ql, qr)) return INT_MIN;
103+
if (l == r) return l;
104+
int mid = (l + r) >> 1, ret = INT_MIN;
105+
if (mid + 1 < v) ret = query4(p->r, mid + 1, r, v, ql, qr);
106+
return ret != INT_MIN ? ret : query4(p->l, l, mid, v, ql, qr);
107+
}
108+
int query5(Node*& p, int l, int r, int v, int ql, int qr) {
109+
if (!query(p, ql, qr)) return INT_MAX;
110+
if (l == r) return l;
111+
int mid = (l + r) >> 1, ret = INT_MAX;
112+
if (mid > v) ret = query5(p->l, l, mid, v, ql, qr);
113+
return ret != INT_MAX ? ret : query5(p->r, mid + 1, r, v, ql, qr);
114+
}
115+
116+
public:
117+
SegmentTree(void) { root = nullptr; }
118+
void update(int p, int v) { return update(root, -1e8, +1e8, v, p); }
119+
int query1(int l, int r, int v) { return query1(root, -1e8, +1e8, v - 1, l, r) + 1; }
120+
int query2(int l, int r, int v) { return query2(root, -1e8, +1e8, v, l, r); }
121+
int query4(int l, int r, int v) { return query4(root, -1e8, +1e8, v, l, r); }
122+
int query5(int l, int r, int v) { return query5(root, -1e8, +1e8, v, l, r); }
123+
} ST;
124+
125+
int a[maxn];
126+
127+
void solve(void) {
128+
int n, q;
129+
cin >> n >> q;
130+
for (int i = 1; i <= n; i++) cin >> a[i], ST.update(i, a[i]);
131+
while (q--) {
132+
int op;
133+
cin >> op;
134+
if (op == 1) {
135+
int l, r, x;
136+
cin >> l >> r >> x, cout << ST.query1(l, r, x) << endl;
137+
} else if (op == 2) {
138+
int l, r, k;
139+
cin >> l >> r >> k, cout << ST.query2(l, r, k) << endl;
140+
} else if (op == 3) {
141+
int p, x;
142+
cin >> p >> x, ST.update(-p, a[p]), ST.update(p, a[p] = x);
143+
} else if (op == 4) {
144+
int l, r, x;
145+
cin >> l >> r >> x, cout << ST.query4(l, r, x) << endl;
146+
} else {
147+
int l, r, x;
148+
cin >> l >> r >> x, cout << ST.query5(l, r, x) << endl;
149+
}
150+
}
151+
return;
152+
}
153+
154+
bool mem2;
155+
156+
int main() {
157+
ios::sync_with_stdio(false), cin.tie(nullptr);
158+
#ifdef LOCAL
159+
cerr << "Memory Cost: " << abs(&mem1 - &mem2) / 1024. / 1024. << "MB" << endl;
160+
#endif
161+
162+
int _ = 1;
163+
while (_--) solve();
164+
165+
#ifdef LOCAL
166+
cerr << "Time Cost: " << clock() * 1000. / CLOCKS_PER_SEC << "MS" << endl;
167+
#endif
168+
return 0;
169+
}

0 commit comments

Comments
 (0)