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

Description

小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似。

小Hi:你说的是哪两个啊?

小Ho:就是二叉排序树和堆啊,你看这两种数据结构都是构造了一个二叉树,一个节点有一个父亲和两个儿子。 如果用1..n的数组来存储的话,对于二叉树上的一个编号为k的节点,其父亲节点刚好是k/2。并且它的两个儿子节点分别为k2和k2+1,计算起来非常方便呢。

小Hi:没错,但是小Hi你知道有一种办法可以把堆和二叉搜索树合并起来,成为一个新的数据结构么?

小Ho:这我倒没想过。不过二叉搜索树满足左子树<根节点<右子树,而堆是满足根节点小于等于(或大于等于)左右儿子。这两种性质是冲突的啊?

小Hi:恩,你说的没错,这两种性质的确是冲突的。

小Ho:那你说的合并是怎么做到的?

小Hi:当然有办法了,其实它是这样的....

Input

第1行:1个正整数n,表示操作数量,10≤n≤100,000

第2..n+1行:每行1个字母c和1个整数k:

若c为'I',表示插入一个数字k到树中,-1,000,000,000≤k≤1,000,000,000

若c为'Q',表示询问树中不超过k的最大数字

Output

若干行:每行1个整数,表示针对询问的回答,保证一定有合法的解

Sample Input

5

I 3

I 2

Q 3

I 5

Q 4

Sample Output

3

3

Http

Hihocoder:http://hihocoder.com/problemset/problem/1325?sid=1122544

Source

二叉平衡树 Treap

解决思路

Treap学习题(待以后补充)

代码

/*
警告:本题代码或许在指针使用上存在问题,等待博主重构数组版。(虽然说这份代码能在Hihocoder上通过,但有读者反映可能会出现RE)
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std; class Treap
{
public:
int key,ran;
int size;
Treap * ch[2];
Treap(int k)
{
key=k;
ran=rand();
ch[0]=ch[1]=NULL;
size=1;
}
int compare(int k)
{
if (k==key)
return -1;
return k<key?0:1;
}
void maintain()
{
size=1;
if (ch[0]!=NULL)
size+=ch[0]->size;
if (ch[1]!=NULL)
size+=ch[1]->size;
}
}; const int inf=2147483647; int n; void Rotate(Treap* &T,int f);//0代表左旋,1代表右旋
void Insert(Treap* &T,int value);
int Find(Treap * T,int value);
int Find_k(Treap * T,int value);
void print(Treap *T); int main()
{
Treap* root=NULL;
cin>>n;
for (int i=1;i<=n;i++)
{
char ch;
int x;
cin>>ch>>x;
if (ch=='I')
{
//cout<<"x "<<x<<endl;
Insert(root,x);
}
else
{
//cout<<Find(root,x)<<"aa"<<endl;
cout<<Find_k(root,x)<<endl;
}
//cout<<i<<":"<<endl;
//print(root);
//cout<<endl;
}
} void Rotate(Treap* &T,int f)
{
Treap* son=T->ch[f^1];//左旋处理的是右子树,而右旋处理的是左子树
T->ch[f^1]=son->ch[f];
son->ch[f]=T;
T->maintain();
son->maintain();
T=son;
} void Insert(Treap* &T,int value)
{
if (T==NULL)
T=new Treap(value);
else
{
int f=value<(T->key) ? 0 :1;
//cout<<value<<' '<<f<<' '<<(T->ch[0]==NULL)<<(T->ch[1]==NULL)<<endl;
Insert(T->ch[f],value);
if ((T->ch[f]->ran)>(T->ran))
Rotate(T,f^1);//如果是右子树则左旋,如果是左子树则右旋
}
T->maintain();
} int Find(Treap * T,int value)
{
while (T!=NULL)
{
//cout<<"Find_In"<<endl;
int f=T->compare(value);
if (f==-1)
return 1;
T=T->ch[f];
}
return 0;
} int Find_k(Treap * T,int value)
{
//cout<<"In"<<endl;
//cout<<T->ch[0]<<' '<<T->ch[1]<<endl;
//int Ans=T->key;
//cout<<"Init_Ans:"<<Ans<<endl;
int Ans=-inf;
while (T!=NULL)
{
//cout<<"Find_k :"<<T->key<<endl;
//cout<<value<<' '<<T->key<<endl;
if (T->key<=value)
Ans=max(Ans,T->key);
int f=T->compare(value);
if (f==-1) return value;
T=T->ch[f];
//Ans=T->key;
}
return Ans;
} void Delete(Treap* &T,int value)
{
int f=T->compare(value);
if (f==-1)
{
Treap* &T2=T;//因为后面要修改T指向,所以先用一个T2存下指针
if (T->ch[0]==NULL)
{
T=T->ch[1];
delete T2;
T2=NULL;
}
else
if (T->ch[1]==NULL)
{
T=T->ch[0];
delete T2;
T2=NULL;
}
else
{
int f2=T->ch[0]->ran > T->ch[1]->ran ? 1:0;
Rotate(T,f2);
Delete(T->ch[f2],value);
}
}
else Delete(T->ch[f],value);
if (T!=NULL)
T->maintain();
} void print(Treap *T)
{
if (T==NULL)
return;
cout<<T->key<<'(';
print(T->ch[0]);
cout<<',';
print(T->ch[1]);
cout<<')';
return;
}

Hihocoder 1325 平衡树·Treap(平衡树,Treap)的更多相关文章

  1. HihoCoder 1325 平衡树·Treap

    HihoCoder 1325 平衡树·Treap 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说 ...

  2. [BZOJ3223]文艺平衡树 无旋Treap

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Description 您需要写一种数据结构(可参考题目标题),来维护一个 ...

  3. bzoj3224: Tyvj 1728 普通平衡树(平衡树)

    bzoj3224: Tyvj 1728 普通平衡树(平衡树) 总结 a. cout<<(x=3)<<endl;这句话输出的值是3,那么对应的,在splay操作中,当父亲不为0的 ...

  4. 【HIHOCODER 1325】 平衡树·Treap

    描述 小Ho:小Hi,我发现我们以前讲过的两个数据结构特别相似. 小Hi:你说的是哪两个啊? 小Ho:就是二叉排序树和堆啊,你看这两种数据结构都是构造了一个二叉树,一个节点有一个父亲和两个儿子. 如果 ...

  5. BZOJ3223文艺平衡树——非旋转treap

    此为平衡树系列第二道:文艺平衡树您需要写一种数据结构,来维护一个有序数列,其中需要提供以下操作: 翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 ...

  6. BZOJ3224普通平衡树——非旋转treap

    题目: 此为平衡树系列第一道:普通平衡树您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数, ...

  7. BZOJ3786星系探索——非旋转treap(平衡树动态维护dfs序)

    题目描述 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球没有依赖星球. ...

  8. BZOJ3159决战——树链剖分+非旋转treap(平衡树动态维护dfs序)

    题目描述 输入 第一行有三个整数N.M和R,分别表示树的节点数.指令和询问总数,以及X国的据点. 接下来N-1行,每行两个整数X和Y,表示Katharon国的一条道路. 接下来M行,每行描述一个指令或 ...

  9. BZOJ3729Gty的游戏——阶梯博弈+巴什博弈+非旋转treap(平衡树动态维护dfs序)

    题目描述 某一天gty在与他的妹子玩游戏.妹子提出一个游戏,给定一棵有根树,每个节点有一些石子,每次可以将不多于L的石子移动到父节点,询问将某个节点的子树中的石子移动到这个节点先手是否有必胜策略.gt ...

随机推荐

  1. 【JAVAWEB学习笔记】网上商城实战:环境搭建和完成用户模块

    网上商城实战 今日任务 完成用户模块的功能 1.1      网上商城的实战: 1.1.1    演示网上商城的功能: 1.1.2    制作目的: 灵活运用所学知识完成商城实战. 1.1.3    ...

  2. Java servlet ajax

    AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下. AJAX = 异步 JavaScript 和 XML. AJAX 是一种用于创建快速动态网页的技术. http://w ...

  3. 【2017-06-02】Jquery基础

    Jquery就是Js集成的一些方法包. 注意:Jquery的引入位置在<head></head>里. 一.选择器 1.Id选择器 $("#div1") 2. ...

  4. spring-boot开发:使用内嵌容器进行快速开发及测试

    一.简述一下spring-boot微框架 1.spring-boot微框架是什么? 大家都知道,在使用spring框架进行应用开发时需要很多*.xml的初始化配置文件,而springBoot就是用来简 ...

  5. 小白审计JACKSON反序列化漏洞

    1. JACKSON漏洞解析 poc代码:main.java import com.fasterxml.jackson.databind.ObjectMapper; import com.sun.or ...

  6. Eclipse中SVN设置文件为ignore后重新添加至版本控制

    先前把需要版本控制的文件夹ignore了,用了很长时间找解决方法,结果发现竟如此简单,对eclipse的功能不熟悉啊. 方法如下: 在Window->Show View -> Naviga ...

  7. 一致性Hash算法与代码实现

    一致性Hash算法: 先构造一个长度为232的整数环(这个环被称为一致性Hash环),根据节点名称的Hash值(其分布为[0, 232-1])将服务器节点放置在这个Hash环上,然后根据数据的Key值 ...

  8. 信号处理——卷积(convolution)的实现

    作者:桂. 时间:2017-03-07  22:33:37 链接:http://www.cnblogs.com/xingshansi/p/6517301.html 前言 信号时域.频域对应关系,及其D ...

  9. Blockly编程:用Scratch制作游戏愤怒的小牛(小鸟)

    愤怒的小鸟曾经很热门,网上还说他是程序员最喜欢玩的游戏.最先我是WIKIOI的评测页面看到他的,后来在2014年全国信息学奥林匹克联赛第一天第三题飞扬的小鸟也看到了它.因此,突然想做一个类似愤怒的小鸟 ...

  10. Feign使用Hystrix无效原因及解决方法

    最近项目重构使用了Spring Boot和Spring Cloud.这两者结合确实给项目带来了方便,同时也遇到了一些问题.其中使用feign作为服务消费,但是断路器hystrix一直不起作用让人很费解 ...