spoj 3273 Treap
2015-08-02 14:59
363 查看
算是一道比较全面的模板题了吧,需要注意的是:查找比x小的元素个数时x不一定在Treap中,解决办法是插入x,查询,再删除x。
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> using namespace std; struct Node { Node * ch[2]; int v, r, size; int cmp( int x ) { if ( x == v ) return -1; return x < v ? 0 : 1; } void maintain() { size = 1; if ( ch[0] != NULL ) size += ch[0]->size; if ( ch[1] != NULL ) size += ch[1]->size; } }; void rotate( Node * & o, int d ) { Node * k = o->ch[d ^ 1]; o->ch[d ^ 1] = k->ch[d]; k->ch[d] = o; o->maintain(); k->maintain(); o = k; } void insert( Node * & o, int x ) { if ( o == NULL ) { o = new Node(); o->ch[0] = o->ch[1] = NULL; o->v = x; o->r = rand(); o->size = 1; } else { int d = o->cmp(x); insert( o->ch[d], x ); if ( o->ch[d]->r > o->r ) { rotate( o, d ^ 1 ); } else { o->maintain(); } } } void remove( Node * & o, int x ) { int d = o->cmp(x); if ( d == -1 ) { if ( o->ch[0] != NULL && o->ch[1] != NULL ) { int dd = ( o->ch[0]->r > o->ch[1]->r ? 1 : 0 ); rotate( o, dd ); remove( o->ch[dd], x ); } else { Node * u = o; if ( o->ch[0] == NULL ) o = o->ch[1]; else o = o->ch[0]; delete u; } } else { remove( o->ch[d], x ); } if ( o != NULL ) o->maintain(); } int ranker( Node * o, int x, int sum ) { int d = o->cmp(x); if ( d == -1 ) { return sum + ( o->ch[0] == NULL ? 0 : o->ch[0]->size ); } else if ( d == 0 ) { return ranker( o->ch[0], x, sum ); } else { int tmp = ( o->ch[0] == NULL ? 0 : o->ch[0]->size ); return ranker( o->ch[1], x, sum + tmp + 1 ); } } int kth( Node * o, int k ) { int tmp = ( o->ch[0] == NULL ? 0 : o->ch[0]->size ); if ( k == tmp + 1 ) return o->v; else if ( k < tmp + 1 ) return kth( o->ch[0], k ); else return kth( o->ch[1], k - tmp - 1 ); } int find( Node * o, int x ) { if ( o == NULL ) return 0; int d = o->cmp(x); if ( d == -1 ) return 1; return find( o->ch[d], x ); } int main () { Node * root = NULL; char op[2]; int q, num; scanf("%d", &q); while ( q-- ) { scanf("%s%d", op, &num); if ( op[0] == 'I' ) { if ( !find( root, num ) ) { insert( root, num ); } } else if ( op[0] == 'D' ) { if ( find( root, num ) ) { remove( root, num ); } } else if ( op[0] == 'K' ) { int s = ( root == NULL ? 0 : root->size ); if ( num > s ) { printf("invalid\n"); } else { printf("%d\n", kth( root, num )); } } else { if ( find( root, num ) ) { printf("%d\n", ranker( root, num, 0 )); } else { insert( root, num ); printf("%d\n", ranker( root, num, 0 )); remove( root, num ); } } } return 0; }
相关文章推荐
- 单例模式
- RIP协议之初级篇
- linux sed替换命令s举例
- 【Android多媒体】Android5.0 NuPlayer多媒体框架【1】
- Controlling How NSThread and NSRunLoop Exit
- HDU 1599 find the mincost route (无向图的最小环)
- Redis 数据结构
- HDU3415
- 大数据系统的浅显易懂理解
- 存储过程分页(3)
- 添加动作
- 无符号整形
- bzoj2038: [2009国家集训队]小Z的袜子(hose)
- POJ 3641 素数打表+快速幂 简单题
- HDU 2045 不容易系列之(3)―― LELE的RPG难题(递推 or 动态规划)
- C语言:十进制到八进制转换(用栈实现)
- IoBuffer常用方法
- CSS背景图拉伸不变形
- spring配置文件详解
- JQuery(一)