BZOJ 3224: Tyvj 1728 普通平衡树
贴个模板:
顺便说一句,貌似在BZOJ上撒时间种子会RE?
/**************************************************************
Problem: 3224
User: unicornt
Language: C++
Result: Accepted
Time:440 ms
Memory:3172 kb
****************************************************************/
#include<cstdio>
#include<cstdlib>
#include<ctime>
const int M=100005;
int sz,ans;
int val[M],key[M],ch[M][2],siz[M],cnt[M];
struct Treap{
int root;
Treap(){
root=0;
}
void Newnode(int&k){
k=++sz;
ch[k][0]=ch[k][1]=0;
siz[k]=cnt[k]=1;
key[k]=rand();
}
void insert(int&k,int x){
if(!k){
Newnode(k);
val[k]=x;
return;
}
siz[k]++;
if(x==val[k]) cnt[k]++;
else{
bool d=x>val[k];
insert(ch[k][d],x);
if(key[ch[k][d]]<key[k]) rotate(k,d^1);
}
}
void push_up(int x){
siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];
}
void rotate(int&x,int f){//0—>left rotate 1->right rotate
int son=ch[x][f^1];
ch[x][f^1]=ch[son][f];
ch[son][f]=x;
push_up(x);
push_up(son);
x=son;
}
int Ask(int k){//num of number less than k
int x=root,tot=0;
while(true){
if(val[x]>k) x=ch[x][0];
else if(val[x]==k) return tot+siz[ch[x][0]]+1;
else tot+=siz[ch[x][0]]+cnt[x],x=ch[x][1];
}
return tot;
}
void Del(int&k,int x){
if(val[k]==x){
if(cnt[k]>1){
cnt[k]--;
siz[k]--;
return;
}
if(ch[k][0]&&ch[k][1]){
bool kind=key[ch[k][0]]>key[ch[k][1]];
rotate(k,kind);
Del(ch[k][kind],x);
}else{
cnt[k]--;
siz[k]--;
if(!ch[k][0]) k=ch[k][1];
else k=ch[k][0];
}
}else Del(ch[k][val[k]<x],x);
if(k) push_up(k);
}
void find_pre(int x,int k){
if(!x) return;
if(val[x]>=k) find_pre(ch[x][0],k);
else{
ans=x;
find_pre(ch[x][1],k);
}
}
void find_nxt(int x,int k){
if(!x) return;
if(val[x]<=k) find_nxt(ch[x][1],k);
else{
ans=x;
find_nxt(ch[x][0],k);
}
}
int find(int k){//find the kth
int x=root;
while(true){
if(siz[ch[x][0]]>=k) x=ch[x][0];
else if(siz[ch[x][0]]+cnt[x]>=k) return val[x];
else{
k-=siz[ch[x][0]]+cnt[x];
x=ch[x][1];
}
}
return val[x];
}
}treap;
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
int opt,x;
scanf("%d%d",&opt,&x);
switch(opt){
case 1:
treap.insert(treap.root,x);
break;
case 2:
treap.Del(treap.root,x);
break;
case 3:
printf("%d\n",treap.Ask(x));
break;
case 4:
printf("%d\n",treap.find(x));
break;
case 5:
ans=0;
treap.find_pre(treap.root,x);
printf("%d\n",val[ans]);
break;
case 6:
ans=0;
treap.find_nxt(treap.root,x);
printf("%d\n",val[ans]);
break;
}
}
return 0;
}