题目链接: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; }