BZOJ3224/LOJ104 普通平衡树 pb_ds库自带红黑树

时间:2021-05-10 02:01:12

您需要写一种数据结构,来维护一些数,其中需要提供以下操作:
1. 插入x
2. 删除x(若有多个相同的数,因只删除一个)
3. 查询x的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

1.n的数据范围:$n<=100000$
2.每个数的数据范围:$[-2e9,2e9]$
 
题解:
 STL太强辣!
 定义
tree<pt,null_type,less< pt >,rb_tree_tag,tree_order_statistics_node_update> t;
逐个解释:
null_type无映射(BZOJ的低版本g++为null_mapped_type)
less<int>从小到大排序
rb_tree_tag 红黑树(splay_tree_tag)
tree_order_statistics_node_update结点更新 接口:
插入t.insert();
删除t.erase();
Rank:t.order_of_key();
第K值:t.find_by_order();
前驱:t.lower_bound();
后继t.upper_bound();
join(b)b并入a 前提是两棵树的key的取值范围不相交
split(v,b)key小于等于v的元素属于a,其余的属于b
lower_bound(x) >=x的min的迭代器
upper_bound((x) >x的min的迭代器
find_by_order(k) 有k个数比它小的数 头文件可以直接用
bits/extc++.h
速度居然也很快,用了读入输出优化之后和我手写的treap并驾齐驱甚至更快(不过这题数据量并不大)
BZOJ3224/LOJ104 普通平衡树  pb_ds库自带红黑树BZOJ
 BZOJ3224/LOJ104 普通平衡树  pb_ds库自带红黑树LOJ
#define _EXT_CODECVT_SPECIALIZATIONS_H 1
#define _EXT_ENC_FILEBUF_H 1
#undef __MINGW32__
#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
using namespace __gnu_pbds;
#define ll long long
template<typename t>
inline const t& read(t& s) {
t x(0),c(1);
char ch(' ');
while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
while(ch=='-') c*=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return s=x*c;
}
template<typename t>
inline void write(t x) {
unsigned long long y(10),len(1);
while(y<=x) y*=10,len++;
while(len--) y/=10,putchar(x/y+48),x%=y;
}
int n,k;
ll x;
tree<ll,null_mapped_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> t;
int main() {
read(n);
for(int i=1; i<=n; i++) {
read(k),read(x);
switch(k) {
case 1:t.insert((x<<20)+i);break;
case 2:t.erase(t.lower_bound(x<<20));break;
case 3:write(t.order_of_key(x<<20)+1);putchar('\n');break;
case 4:write(*t.find_by_order(x-1)>>20);putchar('\n');break;
case 5:write(*--t.lower_bound(x<<20)>>20);putchar('\n');break;
case 6:write(*t.lower_bound((x+1)<<20)>>20);putchar('\n');
}
}
}