输入

第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. Spring笔记:事务管理

    Spring笔记:事务管理 事务管理 Spring事务管理是通过SpringAOP去实现的.默认情况下Spring在执行方法抛出异常后,引发事务回顾,当然你可以用拦截器或者配置去改变它们. 这部门内容 ...

  2. DEC VT100 terminal

  3. Keepalived 主备配置

    keepalived主备或多主多备,配置都是一样配置方法,只是搭建多少的问题. 1.keepalived安装 参考:https://www.cnblogs.com/zwcry/p/9542867.ht ...

  4. Shell编程之case条件

    一.case条件语句 1.语法 case "变量" in 值 1) 指令 1... ;; 值 2) 指令 2... ;; *) 指令 3... esac case条件语句的执行流程 ...

  5. [SCOI2013]火柴棍数字(背包)

    题目 做饭 由于越高位越好,我们先得出能组成的最高位 \(f[i][j][k]\)表示从低到高位第\(i\)位,手里拿着\(j\)根火柴,第\(i\)位是否为\(0\)所需要的最少火柴 我们转移仅需得 ...

  6. console.log()方法中%s的作用

    一.console.log("log信息"); 二.console.log("%s","first","second") ...

  7. HISAT2的运用

    功能: 用于有参考基因组存在的比对工具(适用于whole-genome, transcriptome, and exome sequencing data) 用法: hisat2-build [opt ...

  8. scope 作用域

    每当一个指令被创建的时候,都会面临一个选择:继承父作用域,还是创建一个自己的作用域.Angular为指令的scope参数提供了三种选择,分别是: false(继承), true(不继承), {},默认 ...

  9. Go Interface概念

    简单地说 Interface是一组Method的组合,可以通过Interface来定义对象的一组行为.如果某个对象实现了某个接口的所有方法,就表示它实现了该借口,无需显式地在该类型上添加接口说明.In ...

  10. 用javascript实现的验证码

    <html xmlns="http://www.w3.org/1999/xhtml"><head runat="server">     ...