Hihocoder 1329 平衡树·Splay(平衡树)
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(平衡树)的更多相关文章
- Hihocoder 1329(splay)
Problem 平衡树 Splay 题目大意 维护一个数列,支持三种操作. 操作1:添加一个数x. 操作2:询问不超过x的最大的数. 操作三:删除大小在区间[a,b]内的数. 解题分析 和上一题相比, ...
- JZYZOJ1998 [bzoj3223] 文艺平衡树 splay 平衡树
http://172.20.6.3/Problem_Show.asp?id=1998 平衡树区间翻转的板子,重新写一遍,给自己码一个板子. #include<iostream> #incl ...
- Luogu P3391 【模板】文艺平衡树 Splay 平衡树
https://www.luogu.org/problemnew/show/P3391 以前写过题解的入门题重写练板子.wdnmd真就 ' == ' 写成 ' = ' 了编译器不报错呗. #inclu ...
- luoguP3391[模板]文艺平衡树(Splay) 题解
链接一下题目:luoguP3391[模板]文艺平衡树(Splay) 平衡树解析 这里的Splay维护的显然不再是权值排序 现在按照的是序列中的编号排序(不过在这道题目里面就是权值诶...) 那么,继续 ...
- hiho #1329 : 平衡树·Splay
#1329 : 平衡树·Splay 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. ...
- 【BZOJ3224】Tyvj 1728 普通平衡树 Splay
Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数 ...
- BZOJ3224/洛谷P3391 - 普通平衡树(Splay)
BZOJ链接 洛谷链接 题意简述 模板题啦~ 代码 //普通平衡树(Splay) #include <cstdio> int const N=1e5+10; int rt,ndCnt; i ...
- 文艺平衡树 Splay 学习笔记(1)
(这里是Splay基础操作,reserve什么的会在下一篇里面讲) 好久之前就说要学Splay了,结果苟到现在才学习. 可能是最近良心发现自己实在太弱了,听数学又听不懂只好多学点不要脑子的数据结构. ...
- 【阶梯报告】洛谷P3391【模板】文艺平衡树 splay
[阶梯报告]洛谷P3391[模板]文艺平衡树 splay 题目链接在这里[链接](https://www.luogu.org/problemnew/show/P3391)最近在学习splay,终于做对 ...
随机推荐
- SpringBoot日记——ElasticSearch全文检索
看到标题的那一串英文,对于新手来说一定比较陌生,而说起检索,应该都知道吧. 这个ElasticSearch目前我们的首选,他主要有可以提供快速的存储.搜索.分析海量数据的作用.他是一个分布式搜索服务, ...
- 解决Jira和Confluence访问打开越来越缓慢问题
Jira和Confluence部署在同一台服务器上,跑一段时间后,发现访问jira和confluence时,打开越来越缓慢.这是因为根据主机物理内存不同,默认的java虚拟机内存也会不同(一个较低值) ...
- 全景3d
Three.js Tour.js Run.js 3D Css3 酷家乐:https://www.kujiale.com/ 爱空间:http://bj.ikongjian.com/?utm_source ...
- Linux内核分析— —扒开系统调用的三层皮(上)
实验部分 根据系统调用表,选取一个系统调用.我选得是mkdir这个系统调用,其系统调用号为39,即0x27 由于mkdir函数的原型为int mkdir (const char *filename, ...
- <编写有效用例>读书笔记3
<编写有效用例>读书笔记3 第三部分主要内容是对忙于编写用例的人的提示第20章:对每个用例的提示1.每个用例都是一篇散文:这个提示提醒我们将注意力集中与文字而不是图画上,同时帮助了解将要遇 ...
- 第三个Sprint冲刺总结
第三个Sprint冲刺总结 1.燃尽图 2.本阶段总结: 本阶段主要是对产品进行完善和美化,所以工作量不是很多.但要做精,做好并非是一件简单的事情.我们各组员都安排了各自的任务,如参考各行业的优秀ap ...
- ios开发之--CAKeyframeAnimation的详细用法
简单的创建一个带路径的动画效果,比较粗糙,不过事先原理都是一样的, 代码如下: 1,创建动画所需的view -(void)creatView { moveView = [UIView new]; mo ...
- [2017BUAA软件工程]第0次作业
第一部分:结缘计算机 1. 你为什么选择计算机专业?你认为你的条件如何?和这些博主比呢?(必答) 选择计算机专业的一个重要原因是因为计算机专业的就业前景好,由于计算机本身具有的各种优点,现在几乎所有的 ...
- Linux curl 一例
root@PC-RENGUOQIANG:~# curl http://kermit:kermit@192.168.66.182:8080/activiti-rest/service/repositor ...
- 解决vmware与主机无法连通的问题
我们选择NAT方式,来实现Ubuntu的静态IP地址配置. 打开VMware,在顶部依次选择:编辑 > 虚拟网路编辑器,打开虚拟网路编辑器:去掉VMnet0和VMnet1,只保留VMnet8.然 ...