题解:P3369 【模板】普通平衡树
这题有多少种解法啊?
这里介绍一种时间复杂度正确的且不是 pbds 的做法,类似 pbds,在 __gnu_cxx 库里。
一眼望去,这题的六个操作都可以用 vector 实现,那就直接用 vector 做行不行?
需要熟练运用
代码:
#include<bits/stdc++.h>
using namespace std;
int n,op,x;
vector <int> vec;
int main(){
scanf("%d",&n);
while(n--){
scanf("%d %d",&op,&x);
if(op==1) vec.insert(lower_bound(vec.begin(),vec.end(),x),x);
else if(op==2) vec.erase(lower_bound(vec.begin(),vec.end(),x));
else if(op==3) printf("%d\n",lower_bound(vec.begin(),vec.end(),x)-vec.begin()+1);
else if(op==4) printf("%d\n",vec[x-1]);
else if(op==5) printf("%d\n",vec[lower_bound(vec.begin(),vec.end(),x)-vec.begin()-1]);
else printf("%d\n",vec[upper_bound(vec.begin(),vec.end(),x)-vec.begin()]);
}
}
但是 vector 的
所以 vector 是能被卡掉的,虽然我没在网上找到像是卡掉 SPFA 一样的卡掉 vector 教程,但是肯定是能卡掉的。
但是 rope 的
之所以说这个是因为很多人以为它跟块状链表放在一起就误认为它的
由于 rope 并不是真正的用块状链表来实现,所以它的时间复杂度并不等同于块状链表,而是相当于可持久化平衡树的复杂度
O(\log n) 。
感觉这个东西比 rb_tree_tag 都要冷门?
代码:
#include<bits/stdc++.h>
#include<bits/extc++.h>
using namespace std;
using namespace __gnu_cxx;
int n,op,x;
rope<int>a;
int main(){
cin>>n;
while(n--){
cin>>op>>x;
if(op==1) a.insert(lower_bound(a.begin(),a.end(),x)-a.begin(),x);
if(op==2) a.erase(lower_bound(a.begin(),a.end(),x)-a.begin(),1);
if(op==3) cout<<lower_bound(a.begin(),a.end(),x)-a.begin()+1<<endl;
if(op==4) cout<<a[x-1]<<endl;
if(op==5) cout<<a[lower_bound(a.begin(),a.end(),x)-a.begin()-1]<<endl;
if(op==6) cout<<a[upper_bound(a.begin(),a.end(),x)-a.begin()]<<endl;
}
}