在算法竞赛中,我们只需要知道pb_ds都有什么操作,每种操作是干什么的即可,不需要了解的太深入
该题可以直接用pb_ds近乎暴力秒杀,以及运用到启发式合并的思想
AC代码
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
#include <bits/extc++.h>
using namespace __gnu_pbds;
template <class T>
using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
Tree<pair<int, int> > a[200010][2];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
a[0][0].insert(make_pair(x, i));//值,下标
a[0][1].insert(make_pair(i, x));//下标,值
}
int q;
cin >> q;
for (int i = 1; i <= q; i++) {
int t, s, x;
cin >> t >> s >> x;
if (t == 1) {
int num = a[s][1].size();
x = min(x, num);
if (2 * x <= num) {
while (x--) {
auto it = a[s][1].begin();
a[i][1].insert(*it);
a[i][0].insert(make_pair(it->second, it->first));
a[s][1].erase(make_pair(it->first, it->second));
a[s][0].erase(make_pair(it->second, it->first));
}
a[i][0].swap(a[s][0]);
a[i][1].swap(a[s][1]);
} else {
x = num - x;
while (x--) {
auto it = a[s][1].rbegin();
a[i][1].insert(*it);
a[i][0].insert(make_pair(it->second, it->first));
a[s][1].erase(make_pair(it->first, it->second));
a[s][0].erase(make_pair(it->second, it->first));
}
}
} else {
int num = a[s][0].size();
x = a[s][0].order_of_key(make_pair(x, n + 1));
if (2 * x <= num) {
while (x--) {
auto it = a[s][0].begin();
a[i][0].insert(*it);
a[i][1].insert(make_pair(it->second, it->first));
a[s][0].erase(make_pair(it->first, it->second));
a[s][1].erase(make_pair(it->second, it->first));
}
a[i][0].swap(a[s][0]);
a[i][1].swap(a[s][1]);
} else {
x = num - x;
while (x--) {
auto it = a[s][0].rbegin();
a[i][0].insert(*it);
a[i][1].insert(make_pair(it->second, it->first));
a[s][0].erase(make_pair(it->first, it->second));
a[s][1].erase(make_pair(it->second, it->first));
}
}
}
cout << a[i][0].size() << '\n';
}
return 0;
}
定义pb_ds方式
//头文件必须包含
#include <bits/extc++.h>
using namespace __gnu_pbds;
//定义模板
template <class T>
using Tree = tree<T, null_type, less<T>, rb_tree_tag,
tree_order_statistics_node_update>;
Tree<pair<int, int> > a[200010][2];
//直接定义
tree<pair<int, int>, null_type, less<pair<int, int> >, rb_tree_tag,
tree_order_statistics_node_update> a[200010][2];
pb_ds可以直接当作set进行操作,其中insert和erase没有区别
其中最关键的是它的swap()的时间复杂度是常数
find_by_order(k)//找到下标从0开始的第k大(第0大,第1大....)
order_of_key(k)//返回严格小于k的数的数量