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. Flutter - TabBar导航栏切换后,状态丢失

    上一篇讲到了 Flutter - BottomNavigationBar底部导航栏切换后,状态丢失 里面提到了TabBar,这儿专门再写一下吧,具体怎么操作,来不让TabBar的状态丢失.毕竟大家99 ...

  2. 过渡与动画 - 缓动效果&基于贝塞尔曲线的调速函数

    难题 给过渡和动画加上缓动效果是一种常见的手法(比如具有回弹效果的过渡过程)是一种流行的表现手法,可以让界面显得更加生动和真实:在现实世界中,物体A点到B点往往也是不完全匀速的 以纯技术的角度来看,回 ...

  3. Log4net_简单使用

    log4net 有四种主要的组件,分别是Logger(记录器), Repository(库), Appender(附着器)以及 Layout(布局). 第一步:Log4net的安装 Install-P ...

  4. Jq_DOM元素方法跟JQuery 核心函数跟JQuery 事件方法

    JQuery DOM 元素 函数                            描述 .get()                           从队列中删除所有未运行的项目. .ind ...

  5. Telephone Phrases

    There are some common phrases and sentences you can use when speaking on the telephone. The informal ...

  6. Centos7.2下OpenVPN 环境完整部署记录

    关于OpenVPN的有关介绍及为何使用OpenVPN在此就不做赘述了,下面直接记录Centos7.2系统下部署OpenVPN环境的操作过程: 1) 先将本机的yum换成阿里云的yum源 [root@t ...

  7. VC++6.0的使用感想

    VC++6.0是我接触的第一款编程软件,一直以来都是使用这款软件来完成程序的编写,调试,运行.一直以来都是用C语言编写代码.而VC++6.0窗口简洁明了,占用资源少,上手容易,个人表示很喜欢. VC+ ...

  8. 个人博客Week3——案例分析

    一.调研,评测 我使用的bing的WINDOWS客户端,其大致分为四个模块:词典.例句.翻译.应用. (1)“词典”模块 BUG:搜索”http“词条,界面显示http的相关,但是无法再回到最初的主界 ...

  9. Linux内核及分析 第一周 计算机是如何工作的?

    C语言代码: int g(int x) { return x + 5; } int f(int x) { return g(x); } int main(void) { return f(5) + 1 ...

  10. githup地址

    githup地址:https://github.com/caowenjing/test.git