poj 1442 Treap实现名次树
2015-08-02 10:26
316 查看
Treap的入门题目,每个结点多维护一个size表示以它为根的子树的结点数,然后查kth的时候一层一层向下即可。
#include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <ctime> using namespace std; struct Node { Node * ch[2]; int r; int v; int s; int cmp( int x ) { if ( x == v ) return -1; return x < v ? 0 : 1; } void maintain() { s = 1; if ( ch[0] != NULL ) s += ch[0]->s; if ( ch[1] != NULL ) s += ch[1]->s; } }; 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->s = 1; } else { int d = ( x < o->v ? 0 : 1 ); insert( o->ch[d], x ); if ( o->ch[d]->r > o->r ) { rotate( o, d ^ 1 ); } o->maintain(); } } int kth( Node * o, int k ) { int tmp = ( o->ch[0] == NULL ? 0 : o->ch[0]->s ); 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 ); } const int N = 30001; int a ; int main () { int n, m; while ( scanf("%d%d", &n, &m) != EOF ) { Node * root = NULL; for ( int i = 1; i <= n; i++ ) { scanf("%d", a + i); } int tt, cnt = 1; for ( int i = 1; i <= m; i++ ) { scanf("%d", &tt); while ( cnt <= tt ) { insert( root, a[cnt++] ); } printf("%d\n", kth( root, i )); } } return 0; }
相关文章推荐
- HDOJ(1069)最长下降子序列
- easyUI 验证控件应用、自定义、扩展验证 手机号码或电话话码格式
- HDOJ 5339 Untitled 水
- hdu 5340 Three Palindromes(字符串处理+ 回文)
- Redis的五种数据类型
- 水池数目
- 计算麻将的番数
- python socket 编程01-实现基本点对点通信
- n&(n-1)的用法
- iOS Quartz2D - 画文字 和 图片
- 一个很可爱的登录界面带来的灵感
- ubuntu14.04 android设备调试问题
- 【POJ1787】【Charlie's Change】
- tcp粘包、 拆包 与解决方法
- Kafka for uSwitch's Event Pipeline
- hdu 5340 Three Palindromes(manacher)
- NSIS “Win32 Error,Code:740 ,请求的操作需要提升”错误解决方法
- Hibernate学习(7)关系映射
- codeforces 558E E. A Simple Task( 线段树+统计排序)
- topcpder SRM 664 div2 A,B,C BearCheats , BearPlays equalPiles , BearSorts (映射)