题目链接“:3224: Tyvj 1728 普通平衡树
#include<bits/stdc++.h> #include<set> #include<cstdio> #include<iomanip> #include<iostream> #include<string> #include<cstring> #include<algorithm> #define pb push_back #define ll long long #define fi first #define se second #define PI 3.14159265 //#define ls l,m,rt<<1 //#define rs m+1,r,rt<<1|1 #define eps 1e-7 #define pii pair<int,int> typedef unsigned long long ull; const int inf=1e9+1; const int mx=~0u>>1; const int mod=1e9+7; const int maxn=2e5+10; using namespace std; struct treap { struct node { node *ch[2]; int key,siz,wei,cnt; node(int _key,node * f) { ch[0]=ch[1]=f; key=_key; siz=cnt=1; wei=rand(); } void push(){siz=ch[0]->siz+ch[1]->siz+cnt;} }*null,*root; treap() { null=new node(0,0); null->siz=null->cnt=0;null->wei=mx; root=null; } void rot(node *&rt,bool d)//把!d抬上来 { node *c=rt->ch[!d]; rt->ch[!d]=c->ch[d]; c->ch[d]=rt; rt->push();c->push(); rt=c; } void insert(const int &key,node *&rt)//插入 { if(rt==null){rt=new node(key,null);return;} if(key==rt->key) { rt->cnt++; rt->siz++;return ; } bool d=key>rt->key; insert(key,rt->ch[d]); if(rt->wei>rt->ch[d]->wei)rot(rt,!d); rt->push(); } void remove(const int &key,node *&rt)//删除 { if(rt==null)return; bool d=key>rt->key; if(key==rt->key) { if(rt->cnt>1){rt->cnt--;rt->siz--;return ;} d=rt->ch[0]->wei>rt->ch[1]->wei; if(rt->ch[d]==null) { delete rt; rt=null; return ; } rot(rt,!d); remove(key,rt); } else remove(key,rt->ch[d]); rt->push(); } void view(node *rt) { if(rt==null) { return ; } cout<<rt->key<<endl; view(rt->ch[0]); view(rt->ch[1]); } int rank(const int &key,node *rt)//查询key是第几大 { if(rt==null)return 0; if(key==rt->key)return rt->ch[0]->siz+1; if(key<rt->key)return rank(key,rt->ch[0]); else return rt->ch[0]->siz+rt->cnt+rank(key,rt->ch[1]); } node *select(int k,node *rt)//查询第k大 { // cout<<k<<endl; int s=rt->ch[0]->siz+rt->cnt; if(k>rt->ch[0]->siz&&k<=s)return rt; if(k>s)return select(k-s,rt->ch[1]); else return select(k,rt->ch[0]); // if(k<s)return select(k-s,rt->ch[1]); // else return select(k,rt->ch[0]); } int pre(const int &k)//返回第一个比k小的树 { node *t=root; int ret=0; while(t!=null) { if(t->key<k)ret=t->key,t=t->ch[1]; else t=t->ch[0]; } return ret; } int suc(const int &k)//返回第一个比k大的数 { node *t=root; int ret=0; while(t!=null) { if(t->key>k)ret=t->key,t=t->ch[0]; else t=t->ch[1]; } return ret; } }; int main() { int n; treap ac=treap(); scanf("%d",&n); while(n--) { int op,x; scanf("%d %d",&op,&x); if(op==1)ac.insert(x,ac.root); else if(op==2)ac.remove(x,ac.root); else if(op==3)printf("%d ",ac.rank(x,ac.root)); else if(op==4)printf("%d ",ac.select(x,ac.root)->key); else if(op==5)printf("%d ",ac.pre(x)); else printf("%d ",ac.suc(x)); // ac.view(ac.root); } return 0; }