Copy
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <queue>
#include <set>
using namespace std;
#define $int long long
using vii = vector<int>;
using pii = pair<int,int>;
namespace IO{
char buf[(1<<21)],*p1=buf,*p2=buf,buf1[(1<<21)]; int _=0;
#define gc getchar
#define pc putchar
template<class I>
inline I read(I &x){
x=0; I f=1; char c=gc(); if(c==EOF){ return -1; }
while(c<'0'||c>'9'){ if(c=='-'){ f=f*(-1); } c=gc(); }
while(c>='0'&&c<='9'){ x=(x<<1)+(x<<3)+(c^48); c=gc(); }
return x=x*f;
}
template<typename I,typename ...Args>
inline void read(I &a, Args &...args){
read(a),read(args...);
}
template<class I>
inline void write(I x){
if(x==0){ pc('0'); return; }
int tmp=x>0?x:(-x),cnt=0;
if(x<0){ pc('-'); }
while(tmp){ buf[cnt++]=(tmp%10)+'0'; tmp/=10; }
while(cnt){ pc(buf[--cnt]); }
return;
}
template<class I>
inline void chmax(I &x,I y){ return x=max(x,y),void(); }
template<class I>
inline void chmin(I &x,I y){ return x=min(x,y),void(); }
#define out(x) write(x),pc(' ')
#define outn(x) write(x),pc('\n')
#define assi() pc('\t')
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define ROF(i,a,b) for(int i(a);i>=(b);--i)
#define FORs(i,a,b,s) for(int i(a);i<=(b);i+=(s))
#define ROFs(i,a,b,s) for(int i(a);i>=(b);i-=(s))
#define next(i,now) for(int i(link[now]);i;i=edge[i].nexty)
#define each(i,v) for(auto &i:v)
#define all(v) v.begin(),v.end()
#define sqr(k) ((k)*(k))
#define inf 0x3f3f3f3f
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define db double
}using namespace IO;
#define maxn 1000010
#define SIZE 5010
class splay{
public:
int root,tree_cnt;
struct SP_tree{ int son[2],fa,cnt,size,val; }tree[maxn];
int Son(int ID){ return tree[tree[ID].fa].son[1]==ID; }
void connect(int x,int y,int k){ if(x){ tree[x].son[k]=y; } tree[y].fa=x; }
void pushup(int ID){ tree[ID].size=tree[tree[ID].son[0]].size+tree[tree[ID].son[1]].size+tree[ID].cnt; }
void rotate(int ID){
int fa(tree[ID].fa),gra_fa(tree[fa].fa);
int ty_son(Son(ID)),ty_fa(Son(fa));
connect(fa,tree[ID].son[ty_son^1],ty_son);
connect(ID,fa,ty_son^1);
connect(gra_fa,ID,ty_fa);
return pushup(fa),pushup(ID);
}
void Splay(int ID,int goal=0){
for(int index;(index=tree[ID].fa)!=goal;rotate(ID)){
if(tree[index].fa!=goal){ rotate(Son(index)==Son(ID)?index:ID); }
} return (goal==0)?(root=ID):0,void();
}
int NewNode(int val){
tree[++tree_cnt]=(SP_tree){ {0,0},0,1,1,val };
return tree_cnt;
}
void insert(int val){
if(!root){ root=NewNode(val); return; }
int index=root;
while(tree[index].val!=val&&tree[index].son[tree[index].val<val]){
index=tree[index].son[tree[index].val<val];
} if(tree[index].val==val){ ++tree[index].cnt; return Splay(index); }
connect(index,NewNode(val),tree[index].val<val);
Splay(tree[index].son[tree[index].val<val]);
return;
}
void find(int val){
int index=root;
while(tree[index].val!=val&&tree[index].son[tree[index].val<val]){
index=tree[index].son[tree[index].val<val];
} return Splay(index);
}
void erase(int val){
if(!root){ return; }
find(val);
if(tree[root].val!=val){ return; }
if(tree[root].cnt>1){ --tree[root].cnt; return; }
int index=tree[root].son[0];
if(!index){ root=tree[root].son[1]; tree[root].fa=0; return; }
while(tree[index].son[1]){ index=tree[index].son[1]; }
Splay(index,root); connect(index,tree[root].son[1],1);
return root=index,tree[root].fa=0,pushup(root);
}
int get_rk(int val){
find(val);
int lc=tree[tree[root].son[0]].size;
return (tree[root].val<val?(tree[root].cnt+lc):lc)+1;
}
int get_num(int rk){
int index=root;
while(true){
if(tree[tree[index].son[0]].size>=rk){
index=tree[index].son[0];
} else if(tree[tree[index].son[0]].size+tree[index].cnt<rk){
rk-=(tree[tree[index].son[0]].size+tree[index].cnt);
index=tree[index].son[1];
} else{ break; }
} return tree[index].val;
}
int Pre(int val){
find(val);
if(tree[root].val<val){ return tree[root].val; }
int index=tree[root].son[0];
if(!index){ return -2147483647; }
while(tree[index].son[1]){ index=tree[index].son[1]; }
return Splay(index),tree[index].val;
}
int Suf(int val){
find(val);
if(tree[root].val>val){ return tree[root].val; }
int index=tree[root].son[1];
if(!index){ return 2147483647; }
while(tree[index].son[0]){ index=tree[index].son[0]; }
return Splay(index),tree[index].val;
}
}sp;
int main(){
int T=read(_);
while(T--){
int opt=read(_);
switch(opt){
case 1:{
sp.insert( read(_) );
break;
} case 2:{
sp.erase( read(_) );
break;
} case 3:{
outn( sp.get_rk( read(_) ) );
break;
} case 4:{
outn( sp.get_num( read(_) ) );
break;
} case 5:{
outn( sp.Pre( read(_) ) );
break;
} case 6:{
outn( sp.Suf( read(_) ) );
break;
}
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)