题目链接:Click here~~
题意:
设计一个数据结构,可以在log(n)的时间内插入、删除、返回第 k 大、求某值的 rank。
解题思路:
可以给在 treap 的基础上,每个节点加个size 记录总共涵盖多少节点。
调了一天,终于调出来了。好累啊。
对于 null 节点取 size 的时候要格外小心,否则会指针访问未知内存,导致RE。
所以我尝试了使用函数来返回值,果然可以实现空节点取 size 了,哈哈。
贴出来大家交流学习吧。
/*
Title : Treap
Author: nyist_xiaod
Date : 2013.3.19
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
template<typename T>
struct Treap
{
struct Node
{
T value;
int key,size;
Node *lson, *rson;
Node(const T& val):value(val),key(rand()),size(1),lson(NULL),rson(NULL){}
int get_size(){
return this ? size : 0;
}
void up(){
if(this)
size = lson->get_size() + rson->get_size() + 1;
}
};
Node* Root;
/**********************************************/
Treap():Root(NULL){}
void clear(Node* &root)
{
if(root == NULL)
return ;
clear(root->lson);
clear(root->rson);
delete root;
root = NULL;
}
Node* search(const T& value)
{
for(Node *root=Root ; root ; root = value<root->value ? root->lson : root->rson)
if(value == root->value)
return root;
return NULL;
}
void rotate_l(Node* &root)
{
Node* tmp = root->rson;
root->rson = tmp->lson;
tmp->lson = root;
root->up();
tmp->up();
root = tmp;
}
void rotate_r(Node* &root)
{
Node* tmp = root->lson;
root->lson = tmp->rson;
tmp->rson = root;
root->up();
tmp->up();
root = tmp;
}
void insert(Node* &root,const T& value)
{
if(root == NULL)
{
root = new Node(value);
return ;
}
if(value == root->value)
return ;
if(value < root->value)
{
insert(root->lson,value);
if(root->lson->key > root->key)
rotate_r(root);
else
root->up();
}
else
{
insert(root->rson,value);
if(root->rson->key > root->key)
rotate_l(root);
else
root->up();
}
}
void erase(Node* &root,const T& value)
{
if(root == NULL)
return ;
if(value == root->value)
{
if(root->lson && root->rson)
{
if(root->lson->key > root->rson->key)
{
rotate_r(root);
erase(root->rson,value);
}
else
{
rotate_l(root);
erase(root->lson,value);
}
}
else
{
Node* tmp = root;
root = root->rson ? root->rson : root->lson;
delete tmp;
return ;
}
}
else
if(value < root->value)
erase(root->lson,value);
else
erase(root->rson,value);
root->up();
}
Node* kth(Node* root,int k)
{
int lsize = root->lson->get_size();
if(k-1 == lsize)
return root;
else
if(k-1 < lsize)
return kth(root->lson,k);
else
return kth(root->rson,k-lsize-1);
}
int rank(Node* root,const T& value)
{
if(root == NULL)
return 0;
int lsize = root->lson->get_size();
if(value == root->value)
return lsize + 1;
else
if(value < root->value)
return rank(root->lson,value);
else
return lsize + 1 + rank(root->rson,value);
}
void insert(const T& value){
insert(Root,value);
}
void erase(const T& value){
erase(Root,value);
}
void kth(int k){
if(k > Root->get_size())
puts("invalid");
else
printf("%d\n",kth(Root,k)->value);
}
void rank(const T& value){
printf("%d\n",rank(Root,value-1));
}
void debug(Node* u)
{
if(u == NULL)
return ;
puts("<<<");
debug(u->lson);
puts(">>>");
printf(" ^^ %d ^^ prio=> %d\n",u->value,u->key);
puts(">>>>");
debug(u->rson);
puts("<<<<");
}
};
int main()
{
//freopen("in.ads","r",stdin);
int Q,x;
char str[8];
Treap<int> S;
while(~scanf("%d",&Q))
{
S.clear(S.Root);
while(Q--)
{
scanf("%s%d",str,&x);
if(str[0] == 'I')
S.insert(x);
else if(str[0] == 'D')
S.erase(x);
else if(str[0] == 'K')
S.kth(x);
else
S.rank(x);
}
}
return 0;
}