描述


http://www.lydsy.com/JudgeOnline/problem.php?id=3224

Treap模板题.支持如下几种操作:

1.插入;

2.删除;

3.rank(x);

4.kth(k);

5.pre(x);

6.suc(x);

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 7395  Solved: 3124
[Submit][Status][Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
数据如下http://pan.baidu.com/s/1jHMJwO2

Source

分析


写多了就熟了...昨天看了书,今天调试的时候敲了好多遍,感觉满脑子是tree+heap.

p.s.

1.rank,kth,pre,suc函数都可以写成非递归的形式.

2.remove函数有两种写法:

(1).LRJ白书上的方法:

  如果待删除节点只有一个子树,则用该子树代替待删除节点,删除待删除节点即可.如果有两个子树,则将优先值小的(小根堆)子树旋转上去,再在另一  个子树中递归删除待删除节点,每次这样的旋转操作都会减小子树,最终会达到第一种情况.

(2).在题解里看来的方法:

  如果待删除节点没有子树,那么可以直接删除.如果有子树,则不管有两个还是一个,将优先值小的子树旋转上去(这里注意可以将null的优先值设为   INF),然后再在另一个子树中递归删除节点,每次这样的旋转操作都会减小子树,最终会达到第一种情况.

 #include <cstdio>
#include <cstdlib>
using namespace std; const int oo=~0u<<; struct Treap{
struct node{
node* ch[];
int v,s,r,c;
node(int v,node *t):v(v){ ch[]=ch[]=t; r=rand(); s=c=; }
bool operator < (const node &rhs) const { return r<rhs.r; }
void push_up(){ s=ch[]->s+ch[]->s+c; }
}*root,*null;
Treap(){
null=new node(,);
null->s=null->c=;
null->r=oo;
root=null;
}
void rotate(node* &o,bool d){
node* k=o->ch[!d]; o->ch[!d]=k->ch[d]; k->ch[d]=o;
o->push_up(); k->push_up(); o=k;
}
void insert(node* &o,int x){
if(o==null) o=new node(x,null);
else{
if(o->v==x){
o->c++; o->s++;
}
else{
bool d=x>o->v;
insert(o->ch[d],x);
if(o->ch[d]<o) rotate(o,!d);
o->push_up();
}
}
}
void remove(node* &o,int x){
if(o->v==x){
if(o->c>) o->c--;
else{
if(o->ch[]!=null&&o->ch[]!=null){
bool d=o->ch[]<o->ch[];
rotate(o,d); remove(o->ch[d],x);
}
else{
node* u=o;
if(o->ch[]==null) o=o->ch[];
else o=o->ch[];
delete u;
}
}
}
else{
bool d=x>o->v;
remove(o->ch[d],x);
}
if(o!=null) o->push_up();
}
int kth(node* o,int k){
int s=o->ch[]->s+o->c;
if(k>o->ch[]->s&&k<=s) return o->v;
if(k<=o->ch[]->s) return kth(o->ch[],k);
else return kth(o->ch[],k-s);
}
int rank(node *o,int x){
int s=o->ch[]->s+o->c;
if(x==o->v) return o->ch[]->s+;
if(x<o->v) return rank(o->ch[],x);
else return s+rank(o->ch[],x);
}
int pre(int x){
node* t=root;
int ret=;
while(t!=null){
if(t->v<x){
ret=t->v;
t=t->ch[];
}
else t=t->ch[];
}
return ret;
}
int suc(int x){
node *t=root;
int ret=;
while(t!=null){
if(t->v>x){
ret=t->v;
t=t->ch[];
}
else t=t->ch[];
}
return ret;
}
}tree; int main()
{
int n,a,b;
scanf("%d",&n);
while(n--){
scanf("%d%d",&a,&b);
switch(a){
case():tree.insert(tree.root,b);break;
case():tree.remove(tree.root,b);break;
case():printf("%d\n",tree.rank(tree.root,b));break;
case():printf("%d\n",tree.kth(tree.root,b));break;
case():printf("%d\n",tree.pre(b));break;
case():printf("%d\n",tree.suc(b));break;
}
}
return ;
}

BZOJ_3224_普通平衡树_(Treap)的更多相关文章

  1. 初涉平衡树「treap」

    treap:一种平衡的二叉搜索树 什么是treap(带旋) treap=tree+heap,这大家都知道.因为二叉搜索树(BST)非常容易被卡成一条链而影响效率,所以我们需要一种更加平衡的树形结构,从 ...

  2. Hihocoder 1325 平衡树·Treap(平衡树,Treap)

    Hihocoder 1325 平衡树·Treap(平衡树,Treap) Description 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二叉 ...

  3. 洛谷P3369 【模板】普通平衡树(Treap/SBT)

    洛谷P3369 [模板]普通平衡树(Treap/SBT) 平衡树,一种其妙的数据结构 题目传送门 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除 ...

  4. BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树

    BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排 ...

  5. [luogu P3369]【模板】普通平衡树(Treap/SBT)

    [luogu P3369][模板]普通平衡树(Treap/SBT) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删 ...

  6. AC日记——【模板】普通平衡树(Treap/SBT) 洛谷 P3369

    [模板]普通平衡树(Treap/SBT) 思路: 劳资敲了一个多星期: 劳资终于a了: 劳资一直不a是因为一个小错误: 劳资最后看的模板: 劳资现在很愤怒: 劳资不想谈思路!!! 来,上代码: #in ...

  7. 数组splay ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) #include <cstdio> #define Max 100005 #define Inline _ ...

  8. 替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 闲的没事,把各种平衡树都写写 比较比较... 下面是替罪羊树 #include <cstdio> #inc ...

  9. 红黑树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)

    二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) 近几天闲来无事...就把各种平衡树都写了一下... 下面是红黑树(Red Black Tree) 喜闻乐见拿到了luo ...

随机推荐

  1. 无可匹敌的创建job(细化很多细节)

    declare  jobno           binary_integer ;  rm_days         number := 15; --保留多少天的数据,单位天数  rm_hour    ...

  2. 近期专案PM相关收获

    1, 厚黑学讲的有道理, 坏人? 为什么占便宜., 好人为什么当不了坏人是有一定道理的.     -- 作为PM,能力大小居然都能胜任,从这一点上对组员不负责,如下种种都算有则改之无则加勉.      ...

  3. SomeThing of Memcache

    Memcache for .net 文章一: http://blog.csdn.net/dinglang_2009/article/details/6917794 不定时更新

  4. Codevs 1074 食物链 2001年NOI全国竞赛

    1074 食物链 2001年NOI全国竞赛 时间限制: 3 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description 动物王国中有三类动物 A,B ...

  5. 检查mysql数据库是否存在坏表脚本

    #!/bin/bash #此脚本的主要用途是检测mysql服务器上所有的db或者单独db中的坏表 #变量说明 pass mysql账户口令 name mysql账号名称 data_path mysql ...

  6. 【DP_背包专题】 背包九讲

    这段时间看了<背包九讲>,在HUST VJUDGE上找到了一个题单,挑选了其中16道题集中做了下,选题全部是HDU上的题,大多是简单题.目前做了点小总结,大概提了下每道题的思路重点部分,希 ...

  7. 【java版坦克大战---准备篇】 java 绘图

    要写坦克大战当然要先画出坦克.java画图是基础. package com.game; import java.awt.*; import javax.swing.*; public class Pr ...

  8. python三级菜单的实现

    一.作业要求 1.使用字典实现三级菜单功能 2.直接输入前面数字进入下一级菜单 3.按B返回上一级,按Q退出 二.需要知识点 1.if循环 2.for循环,enumerate的用法 3.while循环 ...

  9. eclipse中DDMS的LOGcat只有一列level

    拷贝来源:http://www.cnblogs.com/kobe8/p/4620785.html http://stackoverflow.com/questions/25010393/eclipse ...

  10. 查看Oracle表空间使用情况与增大表空间

    1,查看表空间使用情况 SELECT D.TABLESPACE_NAME, SPACE || 'M' "SUM_SPACE(M)", BLOCKS "SUM_BLOCKS ...