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. .NET持续集成与自动化部署之路第一篇——半天搭建你的Jenkins持续集成与自动化部署系统

    .NET持续集成与自动化部署之路第一篇(半天搭建你的Jenkins持续集成与自动化部署系统) 前言     相信每一位程序员都经历过深夜加班上线的痛苦!而作为一个加班上线如家常便饭的码农,更是深感其痛 ...

  2. Keepalived基础知识-运维小结

    keepalived介绍keepalived观察其名可知,保持存活,在网络里面就是保持在线了,也就是所谓的高可用或热备,它集群管理中保证集群高可用的一个服务软件,其功能类似于heartbeat,用来防 ...

  3. 索引节点(inode)爆满问题处理

    关于磁盘空间中索引节点爆满的问题还是挺多的,借此跟大家分享几个情况: 情况一 在公司一台配置较低的Linux服务器(内存.硬盘比较小)的/data分区内创建文件时,系统提示磁盘空间不足,用df -h命 ...

  4. beta阶段性能指标测试

    性能指标概况 安装耗时 启动耗时 CPU占用 内存占用 电池温度 网络流量 平均值 5.48s 1.04s 1.61% 18.68MB 32.44℃ 93.78B 峰值 131.74s 5.13s 5 ...

  5. Linux内核分析作业第八周

    进程的切换和系统的一般执行过程 一.进程调度的时机 中断处理过程(包括时钟中断.I/O中断.系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用sch ...

  6. 20135323符运锦期中总结----Linux系统的理解及学习心得

    一.网易云课堂 1.各章节总结 第一周:计算机是如何工作的http://www.cnblogs.com/20135323fuyunjin/p/5222787.html 第二周:操作系统是如何工作的ht ...

  7. java数值运算后精度丢失问题

    最近连续俩次遇到运算后数值精度丢失问题,所以记录一下. 问题1:java计算百分比,应该得到57,可返回的就是56 在java代码中 BigDecimal progress; BigDecimal a ...

  8. 安装虚拟环境和Flask

    一.Flask 使用前准备 一. 安装及创建虚拟环境 1. 安装虚拟环境 win + R -> cmd -> pip install virtualenv -> 出现 Success ...

  9. hadoop伪分布式安装之Linux环境准备

    Hadoop伪分布式安装之Linux环境准备 一.软件版本 VMare Workstation Pro 14 CentOS 7 32/64位 二.实现Linux服务器联网功能 网络适配器双击选择VMn ...

  10. shell脚本--文件测试

    文件测试是指测试某一个文件或者目录是否存在 测试文件格式[ 操作符 目录或者文件 ]    注意左括号和操作符之间有一个空格,文件或者目录 与右边的括号之间也有一个空格. -d 测试是否为目录 -e ...