Hihocoder 1329 平衡树·Splay(平衡树)

Description

小Ho:小Hi,上一次你跟我讲了Treap,我也实现了。但是我遇到了一个关键的问题。

小Hi:怎么了?

小Ho:小Hi你也知道,我平时运气不太好。所以这也反映到了我写的Treap上。

小Hi:你是说你随机出来的权值不太好,从而导致结果很差么?

小Ho:就是这样,明明一样的代码,我的Treap运行结果总是不如别人。小Hi,有没有那种没有随机因素的平衡树呢?

小Hi:当然有了,这次我就跟你讲讲一种叫做Splay的树吧。而且Splay树能做到的功能比Treap要更强大哦。

小Ho:那太好了,你快告诉我吧!

Input

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

第2..n+1行:可能包含下面3种规则:

1个字母'I',紧接着1个数字k,表示插入一个数字k到树中,1≤k≤1,000,000,000,保证每个k都不相同

1个字母'Q',紧接着1个数字k。表示询问树中不超过k的最大数字

1个字母'D',紧接着2个数字a,b,表示删除树中在区间[a,b]的数。

Output

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

Sample Input

6

I 1

I 2

I 3

Q 4

D 2 2

Q 2

Sample Output

3

1

Http

Hihocoder:https://hihocoder.com/problemset/problem/1329

Source

平衡树,Splay

解决思路

平衡树Splay

待填坑

(可以参考yyb的教程:http://www.cnblogs.com/cjyyb/p/7499020.html)

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std; const int maxN=10000101;
const int inf=2147483647; class SplayData
{
public:
int fa,ch[2],key,cnt,size;
SplayData()
{
ch[0]=ch[1]=0;
cnt=0;
size=0;
}
}; class SplayTree
{
public:
int cnt;
int root;
SplayData S[maxN];
SplayTree()
{
root=0;
cnt=0;
Insert(-inf);
Insert(inf);
}
void Insert(int x)
{
int now=root;
int nowf=0;
while ((now!=0)&&(S[now].key!=x))
{
nowf=now;
now=S[now].ch[x>S[now].key];
}
if (now==0)
{
cnt++;
now=cnt;
S[cnt].fa=nowf;
S[cnt].cnt=S[cnt].size=1;
S[cnt].key=x;
if (nowf!=0)
S[nowf].ch[x>S[nowf].key]=cnt;
if (root==0)
root=1;
}
else
S[now].cnt++;
Splay(now,0);
return;
}
bool Find(int x)
{
int now=root;
if (root==0)
return 0;
while ((S[now].ch[x>S[now].key]!=0)&&(x!=S[now].key))
{
//cout<<now<<endl;
now=S[now].ch[x>S[now].key];
}
//cout<<now<<endl;
Splay(now,0);
if (x!=S[now].key)
return 0;
return 1;
}
void Rotate(int x)
{
int y=S[x].fa;
int z=S[y].fa;
int k1=S[y].ch[1]==x;
int k2=S[z].ch[1]==y;
S[z].ch[k2]=x;
S[x].fa=z;
S[y].ch[k1]=S[x].ch[k1^1];
S[S[x].ch[k1^1]].fa=y;
S[x].ch[k1^1]=y;
S[y].fa=x;
return;
}
void Splay(const int x,int goal)
{
while (S[x].fa!=goal)
{
int y=S[x].fa;
int z=S[y].fa;
if (z!=goal)
((S[z].ch[0]==y)^(S[y].ch[0]==x))?Rotate(x):Rotate(y);
Rotate(x);
}
if (goal==0)
root=x;
return;
}
int Next(int x,int opt)
{
Find(x);
int now=root;
if ((S[now].key<x)&&(opt==0))
return now;
if ((S[now].key>x)&&(opt==1))
return now;
now=S[now].ch[opt];
while (S[now].ch[opt^1]!=0)
now=S[now].ch[opt^1];
return now;
}
void DeleteRange(int l,int r)
{
Insert(l);
Insert(r);
int prep=Next(l,0);
int nex=Next(r,1);
Splay(prep,0);
Splay(nex,prep);
S[nex].ch[0]=0;
return;
}
void Outp()
{
cout<<"SplaySize:"<<cnt<<endl;
cout<<"Root:"<<root<<endl;
for (int o=1;o<=cnt;o++)
cout<<o<<" "<<S[o].key<<" "<<S[o].ch[0]<<" "<<S[o].ch[1]<<" "<<S[o].fa<<endl;
return;
}
}; int n;
SplayTree SP; int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
char opt;
opt=getchar();
while ((opt!='I')&&(opt!='Q')&&(opt!='D'))
opt=getchar();
if (opt=='I')
{
int k;
scanf("%d",&k);
SP.Insert(k);
}
if (opt=='Q')
{
int k;
scanf("%d",&k);
if (SP.Find(k))
{
printf("%d\n",k);
continue;
}
int prep=SP.Next(k,0);
printf("%d\n",SP.S[prep].key);
}
if (opt=='D')
{
int l,r;
scanf("%d%d",&l,&r);
SP.DeleteRange(l,r);
}
//SP.Outp();
}
return 0;
}

Hihocoder 1329 平衡树·Splay(平衡树)的更多相关文章

  1. Hihocoder 1329(splay)

    Problem 平衡树 Splay 题目大意 维护一个数列,支持三种操作. 操作1:添加一个数x. 操作2:询问不超过x的最大的数. 操作三:删除大小在区间[a,b]内的数. 解题分析 和上一题相比, ...

  2. JZYZOJ1998 [bzoj3223] 文艺平衡树 splay 平衡树

    http://172.20.6.3/Problem_Show.asp?id=1998 平衡树区间翻转的板子,重新写一遍,给自己码一个板子. #include<iostream> #incl ...

  3. Luogu P3391 【模板】文艺平衡树 Splay 平衡树

    https://www.luogu.org/problemnew/show/P3391 以前写过题解的入门题重写练板子.wdnmd真就 ' == ' 写成 ' = ' 了编译器不报错呗. #inclu ...

  4. luoguP3391[模板]文艺平衡树(Splay) 题解

    链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...

  5. hiho #1329 : 平衡树·Splay

    #1329 : 平衡树·Splay 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. ...

  6. 【BZOJ3224】Tyvj 1728 普通平衡树 Splay

    Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...

  7. BZOJ3224/洛谷P3391 - 普通平衡树(Splay)

    BZOJ链接 洛谷链接 题意简述 模板题啦~ 代码 //普通平衡树(Splay) #include <cstdio> int const N=1e5+10; int rt,ndCnt; i ...

  8. 文艺平衡树 Splay 学习笔记(1)

    (这里是Splay基础操作,reserve什么的会在下一篇里面讲) 好久之前就说要学Splay了,结果苟到现在才学习. 可能是最近良心发现自己实在太弱了,听数学又听不懂只好多学点不要脑子的数据结构. ...

  9. 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay

    [阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...

随机推荐

  1. vim-plug 插件安装与操作

    安装 vim-plug curl -fLo ~/.vim/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/juneg ...

  2. Python基础(下)

    前言 print("\n".join([''.join(['*'*((x-y)%3) if((x*0.05)**2+(y*0.1)**2 -1)**3-(x*0.05)**2*(y ...

  3. 事件(event)

    事件概述 委托是一种类型可以被实例化,而事件可以看作将多播委托进行封装的一个对象成员(简化委托调用列表增加和删除方法)但并非特殊的委托,保护订阅互不影响. 基础事件(event) 在.Net中声明事件 ...

  4. macaca使用中问题解决方法整理

    报告老板:很多同学在搭建macaca的环境时候,出现了各种问题,尤其是使用windows的同学,更是复杂且费劲的要命,我这里针对一些遇到的坑,按照从头的搭建开始说起,如下 基本的搭建条件要满足基础环境 ...

  5. 作业20171123 beta-review 成绩

    申诉 对成绩有疑问或不同意见的同学,请在群里[@杨贵福]. 申诉时间截止2017年12月13日 17:00. 成绩 review NABCD-评论 SPEC-评论 bug found 答复 bugfi ...

  6. 毕业设计 之 五 PHP语法学习笔记

    毕业设计 之 四 PHP语法学习笔记 作者:20135216 平台:windows10 软件:XAMPP,DreamWeaver 说明:该笔记是对网站编程语言的详细学习 一.PHP基础 0. 关于环境 ...

  7. Linux内核分析作业第六周

    创建新进程的过程 一.进程的描述 为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. 1.进程控制块PCB——task_struct 操作系统的三大管理功能 进程 ...

  8. java-过滤器、拦截器

    1.基础知识 1.1面向对象编程(OOP).面向切面编程(AOP) 面向对象编程: 将需求功能划分为不同的.相对独立的和封装良好的类,使他们有属于自己的行为,依靠继承和多态等来定义彼此的关系. 面向切 ...

  9. 结对项目https://github.com/bxoing1994/test/blob/master/源代码

    所选项目名称:文本替换      结对人:曲承玉 github地址 :https://github.com/bxoing1994/test/blob/master/源代码 结对人github地址:ht ...

  10. 软件工程项目之摄影App

    摄影app 开发人员:Ives & Dyh 开发功能: 摄影师注册与认证,为年轻摄影师提供成长的空间,发挥一技之长的平台. 用户注册与验证,为有摄影需求的人提供选择摄影师进行个性化拍摄的平台. ...