您需要写一种数据结构,来维护一些数,其中需要提供以下操作:
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并驾齐驱甚至更快(不过这题数据量并不大)
BZOJ
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(' ');break; case 4:write(*t.find_by_order(x-1)>>20);putchar(' ');break; case 5:write(*--t.lower_bound(x<<20)>>20);putchar(' ');break; case 6:write(*t.lower_bound((x+1)<<20)>>20);putchar(' '); } } }