输入

第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]的数。

输出

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

样例输入
6
I 1
I 2
I 3
Q 4
D 2 2
Q 2
样例输出
3
1
 ps:

学习了一周多的后缀自动机,暂时搁下,回去学习平衡树。

离学习treap树已经有两周多了,终于开始学splay了,ORZ平衡树。

一查维基百科,发现tarjan还参与发明了splay树,ORZ:“The splay tree was invented by Daniel Sleator and Robert Tarjan in 1985.

ps:

第一次写,也是抄的模板,加了自己的一些批注。

也做了一点小改动,hihocoder在删去区间[a,b]的时候是先加上点a和b,防止没有这两个点。

而此处的做法是找到最大的x<a,最小的y>b(不能等于!),然后删去x,y之间的,这样就不必加点了。

不过Find(x)函数可以判断是否存在某点,但移到根的不一定是x。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxN=;
const int inf=;
struct SplayData
{
int fa,ch[],key,cnt,size;//cnt是单个节点的数据;size是子树的数据 ,此题不用size;
SplayData()//自动初始每一个新建data
{
ch[]=ch[]=;
cnt=;
size=;
}
}; struct SplayTree
{
int cnt;
int root;
SplayData S[maxN];
SplayTree()//自动初始树
{
root=;
cnt=;
Insert(-inf);//插入极大极小值
Insert(inf);
}
void Insert(int x)
{
int now=root;//root不一定为0 ;
int nowfa=;//上一个now,fa[now];
while (now!=&&S[now].key!=x){
nowfa=now;
now=S[now].ch[x>S[now].key];
}
if (now==){//节点为空 ,新建节点;
cnt++;
now=cnt;
S[cnt].fa=nowfa;//父关系
S[cnt].cnt=S[cnt].size=;
S[cnt].key=x;
if (nowfa!=) S[nowfa].ch[x>S[nowfa].key]=cnt;//子关系
if (root==) root=;//树非空
}
else S[now].cnt++;//节点非空
Splay(now,);
return;
}
bool Find(int x)
{
if (root==) return ;//树为空,肯定找不到
int now=root;
while ((S[now].ch[x>S[now].key]!=)&&(x!=S[now].key)) now=S[now].ch[x>S[now].key];
//nice code!!!
Splay(now,);//不管找到没都把now移到根节点。
if (x!=S[now].key) return ;
return ;
}
void Rotate(int x)
{
int y=S[x].fa;
int z=S[y].fa;
int k1=S[y].ch[]==x;
int k2=S[z].ch[]==y;
S[z].ch[k2]=x;
S[x].fa=z;
S[y].ch[k1]=S[x].ch[k1^];
S[S[x].ch[k1^]].fa=y;
S[x].ch[k1^]=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[]==y)^(S[y].ch[]==x))?Rotate(x):Rotate(y);//异则x,同则y 
Rotate(x);
}
if (goal==)
root=x;
return;
}
int Next(int x,int opt)
{
Find(x);//先移‘x’到根
int now=root;
if ((S[now].key<x)&&(opt==)) return now; //对根做处理
if ((S[now].key>x)&&(opt==)) return now;
now=S[now].ch[opt];
while (S[now].ch[opt^]!=) now=S[now].ch[opt^];//沿子树一直找
return now;
}
void DeleteRange(int l,int r)
{
// Insert(l);//删去
?//Insert(r);
int prep=Next(l,);//移到根
int nex=Next(r,);//移到根的右儿子
Splay(prep,);
Splay(nex,prep);
S[nex].ch[]=;//删去根的右儿子的左儿子
return;
}
};
SplayTree SP;
int main()
{
int k,l,r,n;
scanf("%d",&n);
for (int i=;i<=n;i++){
char opt[];
scanf("%s",opt);
if (opt[]=='I'){
scanf("%d",&k);
SP.Insert(k);
}
else if (opt[]=='Q'){
scanf("%d",&k);
if (SP.Find(k)){//恰好找到
printf("%d\n",k);
continue;
}
int prep=SP.Next(k,);//否则 ,找左子树最大。
printf("%d\n",SP.S[prep].key);
}
else if (opt[]=='D'){
scanf("%d%d",&l,&r);
SP.DeleteRange(l,r);
}
}
return ;
}

像这样没有特殊的处理的,基于同样原理的set还是可以乱搞的。 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<set>
using namespace std;
set<int>q;
int main()
{
int n,i,a,b;
char opt[];
scanf("%d",&n);
while(n--){
scanf("%s",opt);
if(opt[]=='I'){
scanf("%d",&a);
q.insert(a);
}
else if(opt[]=='Q'){
scanf("%d",&a);
set<int>:: iterator it=q.upper_bound(a);
it--;
printf("%d\n",*it);
}
else {
scanf("%d%d",&a,&b);
q.erase(q.lower_bound(a),q.upper_bound(b));
}
}
return ;
}

HihoCoder1329 平衡树·Splay(附STL版)的更多相关文章

  1. HihoCoder1325 : 平衡树·Treap(附STL版本)

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

  2. hiho #1329 : 平衡树·Splay

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

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

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

  4. python实现文章或博客的自动摘要(附java版开源项目)

    python实现文章或博客的自动摘要(附java版开源项目) 写博客的时候,都习惯给文章加入一个简介.现在可以自动完成了!TF-IDF与余弦相似性的应用(三):自动摘要 - 阮一峰的网络日志http: ...

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

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

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

    Hihocoder 1329 平衡树·Splay(平衡树) Description 小Ho:小Hi,上一次你跟我讲了Treap,我也实现了.但是我遇到了一个关键的问题. 小Hi:怎么了? 小Ho:小H ...

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

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

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

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

  9. 平衡树——splay 三

    前文链接: 平衡树--splay 一 - yi_fan0305 - 博客园 (cnblogs.com) 平衡树--splay 二 - yi_fan0305 - 博客园 (cnblogs.com) 再补 ...

随机推荐

  1. (转) GIS 中地理坐标和屏幕坐标的标准转换方法

    from :http://www.cnblogs.com/WonKerr/archive/2010/01/01/Coord_Transform.html 在GIS中,当你拿到一个图层的地理坐标后,如果 ...

  2. python之路 内置函数,装饰器

    一.内置函数 #绝对值 abs() #所有值都为真才为真 all() #只要有一个值为真就为真 any() #10进制转成二进制 bin() #10进制转成八进制 oct() #10进制转成十六进制 ...

  3. SPOJ - HORRIBLE 【线段树】

    思路 线段树 区间更新 模板题 注意数据范围 AC代码 #include <cstdio> #include <cstring> #include <ctype.h> ...

  4. 每天一个Linux命令(43)at命令

        at命令用于在指定时间执行命令.at允许使用一套相当复杂的指定时间的方法.可以用相对时间法指定,也可以用绝对时间法指定.     (1)用法:     用法:  at  [选项参数]  [时间 ...

  5. Mycat实现Mysql数据库读写分离

    Linux和Windows环境下搭建Mycat数据读写分离 前提需要:1.服务器装有JVM虚拟机,就是JDK.2.两个Mysql数据库已经实现主从复制,参考:https://www.cnblogs.c ...

  6. 【HackerRank】Median

    题目链接:Median 做了整整一天T_T 尝试了各种方法: 首先看了解答,可以用multiset,但是发现java不支持: 然后想起来用堆,这个基本思想其实很巧妙的,就是维护一个最大堆和最小堆,最大 ...

  7. php数组函数-array_intersect()

    array_intersect()函数返回两个或多个数组的交集数组 结果数组包含了所有在被比较数组中,也同时出现在所有其他参数数组中 的值,键名保留不变 array_intersect(array1, ...

  8. git上面创建个人简历-链接

    github创建个人在线简历: https://segmentfault.com/a/1190000006820290

  9. Difference between stem and lemma

    lemma与stem的区别 Difference between stem and lemma 先从wikipedia上看看什么是stem,什么是lemma? Lemma(morphology):In ...

  10. Java -- JDBC 批处理

    两种批处理方式: 采用Statement.addBatch(sql)方式实现批处理: •优点:可以向数据库发送多条不同的SQL语句. •缺点: •SQL语句没有预编译. •当向数据库发送多条语句相同, ...