#include <cstdio>
#include <iostream>
#include <algorithm>
#include <ctime>
using namespace std;
struct Node {
int key,fix,cnt,siz; //multi
Node* ch[2];
Node() {}
Node(int);
int dir(int _) {
if(_==key) return -1;
else return _<key?0:1;
}
void maintain() {
siz=ch[0]->siz+ch[1]->siz+cnt;
return;
}
}*null,*root;
void init_null() {
null=new Node();
null->fix=rand();
null->ch[0]=null->ch[1]=null;
null->siz=null->cnt=0;
null->key=20000722;
root=null;
return;
}
Node:: Node(int _): key(_) {
siz=cnt=1;
fix=rand();
ch[0]=ch[1]=null;
}
void print(Node* cur) {
if(cur==null) return;
print(cur->ch[0]);
for(int i=1;i<=cur->cnt;i++) printf("%d ",cur->key);
print(cur->ch[1]);
return;
}
void Rotate(Node* &cur,int dir) {
Node *tmp=cur->ch[dir^1];
cur->ch[dir^1]=tmp->ch[dir];
tmp->ch[dir]=cur;
cur->maintain(),tmp->maintain();
cur=tmp;
return;
}
void treap_ins(Node* &cur,int new_key) {
if(cur==null) {
cur=new Node(new_key);
return;
}
int dir=cur->dir(new_key);
if(!~dir) {
cur->cnt++;
cur->maintain();
return;
}
else {
treap_ins(cur->ch[dir],new_key);
if(cur->fix>cur->ch[dir]->fix) Rotate(cur,dir^1);
cur->maintain();
return;
}
return;
}
void treap_del(Node* &cur,int del_key) {
if(cur==null) return;
int dir=cur->dir(del_key);
if(!~dir) {
Node* tmp=cur;
if(cur->cnt>1) {
cur->cnt--;
cur->maintain();
return;
}
else if(cur->ch[0]==null) {
cur=cur->ch[1];
delete tmp;
tmp=null;
}
else if(cur->ch[1]==null) {
cur=cur->ch[0];
delete tmp;
tmp=null;
}
else {
int dir2=cur->ch[0]->fix>cur->ch[1]->fix?1:0;
Rotate(cur,dir2^1);
treap_del(cur->ch[dir2^1],del_key);
}
}
else treap_del(cur->ch[dir],del_key);
cur->maintain();
return;
}
int k_th(Node* cur,int k) {
int num=cur->cnt+cur->ch[0]->siz;
if(k>num)
return k_th(cur->ch[1],k-num);
else if(k<=cur->ch[0]->siz)
return k_th(cur->ch[0],k);
else
return cur->key;
}
int k_rank(Node* cur,int k) {
if(cur->key==k) return cur->ch[0]->siz;
else if(cur->key<k) return cur->ch[0]->siz+cur->cnt+k_rank(cur->ch[1],k);
else return k_rank(cur->ch[0],k);
}
inline int findpre(Node* cur,int key) {
if(cur==null) return -int(1e9);
if(key<cur->key) return findpre(cur->ch[0],key);
else if(key==cur->key) return key;
else return max(cur->key,findpre(cur->ch[1],key));
}
inline int findnext(Node* cur, int key) {
if(cur==null) return int(1e9);
if(key<cur->key) return min(cur->key,findnext(cur->ch[0],key));
else if(key==cur->key) return key;
else return findnext(cur->ch[1],key);
}
const int maxn=int(1e4)+20;
int n,m;
int add[maxn];
int que[maxn],pt=1;
int main() {
srand(time(0));
init_null();
char op[10];
while(scanf("%s",op)!=EOF) {
if(op[0]=='i') {
int new_key;
scanf("%d",&new_key);
treap_ins(root,new_key);
}
else if(op[0]=='p' && op[2]=='i') {
print(root);
putchar('\n');
continue;
}
else if(op[0]=='d') {
int del_key;
scanf("%d",&del_key);
treap_del(root,del_key);
}
else if(op[0]=='k') {
int k;
scanf("%d",&k);
if(k==1) {
cout<<"root::key:"<<root->key<<endl;
}
printf("%d\n",k_th(root,k));
}
else if(op[0]=='r') {
int k;
scanf("%d",&k);
cout<<k_rank(root,k)+1<<endl;
}
else if(op[0]=='p') {
int k;
scanf("%d",&k);
cout<<findpre(root,k)<<endl;
}
else if(op[0]=='n') {
int k;
scanf("%d",&k);
cout<<findnext(root,k)<<endl;
}
else if(op[0]=='e') {
return 0;
}
}
return 0;
}
(新知)数据结构--Treap--模版
最新推荐文章于 2024-08-15 14:40:56 发布