平衡树
gnu pbds 中的 tree:
普通平衡树
- 插入 数
- 删除 数(若有多个相同的数,应只删除一个)
- 查询 数的排名(排名定义为比当前数小的数的个数 )
- 查询排名为 的数
- 求 的前驱(前驱定义为小于 ,且最大的数)
- 求 的后继(后继定义为大于 ,且最小的数)
__gnu_pbds::tree
不支持可重复集合,需要自己手动处理。
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <iostream>
using namespace std;
using namespace __gnu_pbds;
#define int long long
tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
a;
signed main() {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
int op, x;
cin >> op >> x;
if (op == 1) {
a.insert((x << 20) + i);
} else if (op == 2) {
a.erase(a.lower_bound(x << 20));
} else if (op == 3) {
cout << a.order_of_key(x << 20) + 1 << endl;
} else if (op == 4) {
cout << (*a.find_by_order(x - 1) >> 20) << endl;
} else if (op == 5) {
cout << (*(--a.lower_bound(x << 20)) >> 20) << endl;
} else if (op == 6) {
cout << (*a.lower_bound((x << 20) + n) >> 20) << endl;
}
}
return 0;
}
std::rope
实现区间翻转:
#pragma GCC optimize(2)
#include <ext/rope>
#include <iostream>
using namespace std;
using namespace __gnu_cxx;
void solve() {
rope<int> s, rs;
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
s.push_back(i);
rs.push_back(n - i + 1);
}
while (m--) {
int l, r;
cin >> l >> r;
int rl = n - r + 1;
int rr = n - l + 1;
--l, --r;
--rl, --rr;
auto tmp = s.substr(l, r - l + 1);
auto rtmp = rs.substr(rl, rr - rl + 1);
s = s.substr(0, l) + rtmp + s.substr(r + 1, n - r);
rs = rs.substr(0, rl) + tmp + rs.substr(rr + 1, n - rr);
}
for (auto i : s) {
cout << i << ' ';
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
while (t--) {
solve();
}
}