参考题目:LOJ107
解析:
联赛完了统一更所有模板题解析。
指针实现看这里
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline
ll getint(){
re ll num;
re char c;
while(!isdigit(c=gc()));num=c^48;
while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
return num;
}
inline
void outint(ll a){
static char ch[23];
if(a==0)pc('0');
while(a)ch[++ch[0]]=a-a/10*10,a/=10;
while(ch[0])pc(ch[ch[0]--]^48);
}
cs int N=300005;
struct TREAP{
int lc[N],rc[N];
int val[N];
int p[N];
int siz[N];
int cnt[N];
int tot,root;
TREAP():tot(0),root(0){}
void maintain(int k){
siz[k]=siz[lc[k]]+siz[rc[k]]+cnt[k];
}
void Zig(int &k){
int y=lc[k];
lc[k]=rc[y];
rc[y]=k;
siz[y]=siz[k];
maintain(k);
k=y;
}
void Zag(int &k){
int y=rc[k];
rc[k]=lc[y];
lc[y]=k;
siz[y]=siz[k];
maintain(k);
k=y;
}
void insert(int &k,cs int &key){
if(!k){
k=++tot;
lc[k]=rc[k]=0;
val[k]=key;
p[k]=rand();
siz[k]=cnt[k]=1;
return ;
}
++siz[k];
if(val[k]==key)return (void)(++cnt[k]);
if(val[k]<key){
insert(rc[k],key);
if(p[rc[k]]>p[k])Zag(k);
}
else{
insert(lc[k],key);
if(p[lc[k]]>p[k])Zig(k);
}
}
void Insert(cs int &key){insert(root,key);}
void del(int &k,cs int &key){
if(!k)return;
if(val[k]==key){
if(cnt[k]>1)--cnt[k],--siz[k];
else if(!lc[k]||!rc[k])k=lc[k]+rc[k];
else if(p[lc[k]]<p[rc[k]])Zag(k),del(k,key);
else Zig(k),del(k,key);
return ;
}
--siz[k];
if(key<val[k])del(lc[k],key);
else del(rc[k],key);
}
void Delete(cs int &key){del(root,key);}
int queryrank(cs int &key){
int k=root,ans=0;
while(k){
if(val[k]==key)return ans+siz[lc[k]];
if(key<val[k])k=lc[k];
else ans+=siz[lc[k]]+cnt[k],k=rc[k];
}
return ans;
}
int querykth(int Rank){
int k=root;
while(k){
if(siz[lc[k]]<Rank&&siz[lc[k]]+cnt[k]>=Rank)return val[k];
if(siz[lc[k]]>=Rank)k=lc[k];
else Rank-=siz[lc[k]]+cnt[k],k=rc[k];
}
return 0;
}
int querypre(cs int &k){
int x=root,ans=-0x3f3f3f3f;
while(x){
if(val[x]>=k)x=lc[x];
else ans=val[x],x=rc[x];
}
return ans;
}
int querysuf(cs int &k){
int x=root,ans=0x3f3f3f3f;
while(x){
if(val[x]<=k)x=rc[x];
else ans=val[x],x=lc[x];
}
return ans;
}
}Treap;
int n;
signed main(){
n=getint();
while(n--){
int op=getint(),x=getint();
int ans;
switch(op){
case 0:Treap.Insert(x);break;
case 1:Treap.Delete(x);break;
case 2:outint(Treap.querykth(x)),pc('\n');break;
case 3:outint(Treap.queryrank(x)),pc('\n');break;
case 4:ans=Treap.querypre(x),(ans==-0x3f3f3f3f?puts("-1"):(outint(ans),pc('\n')));break;
case 5:ans=Treap.querysuf(x),(ans==0x3f3f3f3f?puts("-1"):(outint(ans),pc('\n')));break;;
}
}
return 0;
}