分析:一道水题,去年考场发现了特点但是不会splay维护挂了,然后现在我写了个treap。

画一画图就可以解决这道题了,自己试一下。

代码如下:

#include<bits/stdc++.h>
using namespace std; const int maxn = ;
int m,xxx; namespace Treap{
struct spaly{int son[],fa;}t[maxn];
int sz[maxn],ch[maxn][],num,SpalyRoot,Prs[maxn];
int key[maxn],lazy[maxn],dep[maxn],data[maxn],root;
void push_down(int now){
dep[now] += lazy[now];
lazy[ch[now][]] += lazy[now]; lazy[ch[now][]] += lazy[now];
lazy[now] = ;
}
int merge(int root1,int root2){
if(!root1) return root2; if(!root2) return root1;
if(lazy[root1]) push_down(root1); if(lazy[root2]) push_down(root2);
if(key[root1] <= key[root2]){
ch[root1][] = merge(ch[root1][],root2);
Prs[ch[root1][]] = root1;
sz[root1] = sz[ch[root1][]] + sz[ch[root1][]] + ;
return root1;
}else{
ch[root2][] = merge(root1,ch[root2][]);
Prs[ch[root2][]] = root2;
sz[root2] = sz[ch[root2][]] + sz[ch[root2][]] + ;
return root2;
}
}
pair<int,int> split(int Node,int Len){
if(Len == ) return make_pair(,Node);
if(Node == ) return make_pair(,);
if(lazy[Node]) push_down(Node);
if(sz[ch[Node][]] >= Len){
pair<int,int> Ans = split(ch[Node][],Len);
ch[Node][] = Ans.second; Prs[Ans.second] = Node;
Ans.second = Node; Prs[Ans.first] = ;
sz[Node] = sz[ch[Node][]] + sz[ch[Node][]] + ;
return Ans;
}else{
pair<int,int> Ans = split(ch[Node][],Len-sz[ch[Node][]]-);
ch[Node][] = Ans.first; Prs[Ans.first] = Node;
Ans.first = Node; Prs[Ans.second] = ;
sz[Node] = sz[ch[Node][]] + sz[ch[Node][]] + ;
return Ans;
}
}
int get_rank(int Node,int Val){
if(Node == ) return ;
if(data[Node] > Val) return get_rank(ch[Node][],Val);
else return sz[ch[Node][]]++get_rank(ch[Node][],Val);
}
int get_Kth(int Node){
stack<int> sta; int pts = Node;
while(pts){sta.push(pts),pts = Prs[pts];}
int Th = ;
while(!sta.empty()){
int dat = sta.top();sta.pop();
if(lazy[dat]) push_down(dat);
if(!sta.empty()&&ch[dat][] == sta.top()){
Th += sz[ch[dat][]] + ;
}
}
Th += sz[ch[Node][]] + ;
return Th;
}
} namespace operation{
using namespace Treap;
int Insert(int Val){
if(root == ){
root++;sz[root]=;key[root]=rand();data[root]=Val;dep[root]=;
num++;SpalyRoot++;return dep[root];
}
num++;sz[num] = ;key[num] = rand();data[num] = Val;
int rk = get_rank(root,Val);
pair<int,int> nowp = split(root,rk);
int rt = nowp.first,lt = nowp.second;
while(ch[rt][]) {if(lazy[rt])push_down(rt); rt = ch[rt][];}
while(ch[lt][]) {if(lazy[lt])push_down(lt); lt = ch[lt][];}
if(lazy[rt]&&rt) push_down(rt); if(lazy[lt]&&lt) push_down(lt);
if(!t[rt].son[] && rt != ){
t[rt].son[] = num;t[num].fa = rt;dep[num] = dep[rt]+;
}else{
t[lt].son[] = num;t[num].fa = lt;dep[num] = dep[lt]+;
}
root = merge(merge(nowp.first,num),nowp.second);
return dep[num];
}
int Spaly(int Kind){ // 0 min,1 max
int nowp = root;
while(ch[nowp][Kind]){
if(lazy[nowp])push_down(nowp); nowp=ch[nowp][Kind];
}
if(nowp == SpalyRoot){return ;}
int Son = t[nowp].son[Kind^],Father = t[nowp].fa;
t[nowp].son[Kind^] = SpalyRoot; t[SpalyRoot].fa = nowp;
SpalyRoot = nowp;t[nowp].fa = ;int finalans;
int Len = get_Kth(Father);
t[Father].son[Kind] = Son; t[Son].fa = Father;
if(Kind == ){
pair<int,int> Ans = split(root,Len-);
pair<int,int> Cut = split(Ans.first,);
lazy[Ans.second]++;
if(lazy[Cut.first]) push_down(Cut.first);
finalans = dep[nowp]; dep[Cut.first] = ;
root = merge(merge(Cut.first,Cut.second),Ans.second);
}else{
pair<int,int> Ans = split(root,Len);
pair<int,int> Cut = split(Ans.second,sz[Ans.second]-);
lazy[Ans.first]++;
if(lazy[Cut.second]) push_down(Cut.second);
finalans = dep[nowp];dep[Cut.second] = ;
root = merge(Ans.first,merge(Cut.first,Cut.second));
}
return finalans;
}
int Erase(int Kind){//0 min 1 max
int finalans = Spaly(Kind);
int nowp = root;
while(ch[nowp][Kind]){
if(lazy[nowp])push_down(nowp); nowp=ch[nowp][Kind];
}
SpalyRoot = t[nowp].son[Kind^];
t[SpalyRoot].fa = ;t[nowp].son[Kind^] = ;
pair<int,int> Les = split(root,get_Kth(nowp));
pair<int,int> Spt = split(Les.first,get_Kth(nowp)-);
root = merge(Spt.first,Les.second);
if(root != ) lazy[root]--;
return finalans;
}
} void work(){
for(int i=;i<=m;i++){xxx=i;
int opt,x; scanf("%d",&opt);
if(opt == || opt == ) printf("%d\n",operation::Spaly(opt%));
else if(opt == || opt == ) printf("%d\n",operation::Erase(opt%));
else {scanf("%d",&x);printf("%d\n",operation::Insert(x));}
}
} int main(){
srand();
scanf("%d",&m);
work();
return ;
}

BZOJ4825 单旋的更多相关文章

  1. 【BZOJ4825】【HNOI2017】单旋(Link-Cut Tree)

    [BZOJ4825][HNOI2017]单旋(Link-Cut Tree) 题面 题面太长,懒得粘过来 题解 既然题目让你写Spaly 那就肯定不是正解 这道题目,让你求的是最大/最小值的深度 如果有 ...

  2. [BZOJ4825][HNOI2017]单旋(线段树+Splay)

    4825: [Hnoi2017]单旋 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 667  Solved: 342[Submit][Status][ ...

  3. 【BZOJ4825】[Hnoi2017]单旋 线段树+set

    [BZOJ4825][Hnoi2017]单旋 Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能 ...

  4. bzoj4825 [Hnoi2017]单旋

    Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必 ...

  5. BZOJ4825: [Hnoi2017]单旋(Splay)

    题面 传送门 题解 调了好几个小时--指针太难写了-- 因为只单旋最值,我们以单旋\(\min\)为例,那么\(\min\)是没有左子树的,而它旋到根之后,它的深度变为\(1\),它的右子树里所有节点 ...

  6. 【bzoj4825】[Hnoi2017]单旋 线段树+STL-set

    题目描述 H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的必修技能.有一天 ...

  7. 刷题总结——单旋(HNOI2017 bzoj4825)

    题目: Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 ...

  8. 并不对劲的bzoj4825:loj2018:p3721:[HNOI2017]单旋

    题目大意 spaly是一种数据结构,它是只有单旋的splay 有一个初始为空的spaly,\(m\)(\(m\leq10^5\))次操作,每个操作是以下5种中的一种: 1.向spaly中插入一个数(过 ...

  9. [bzoj4825] [loj#2018] [Hnoi2017] 单旋

    Description \(H\) 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(\(splay\))是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构 ...

随机推荐

  1. iterator的romove方法的注意事项

    package cn.lonecloud.Iterator; import java.util.ArrayList; import java.util.Iterator; public class m ...

  2. java5 - 数组与排序算法

    数组是什么? 一.一维数组 1 声明与定义的区别 一般的情况下我们常常这样叙述, 把建立空间的声明称之为"定义", 而把不需要建立存储空间称之为"声明". 很明 ...

  3. Python数据结构之四——set(集合)

    Python版本:3.6.2  操作系统:Windows  作者:SmallWZQ 经过几天的回顾和学习,我终于把Python 3.x中的基础知识介绍好啦.下面将要继续什么呢?让我想想先~~~嗯,还是 ...

  4. SpringBoot Hello World

    本文首发于我的github博客 前言 SpringBoot是Spring MVC升级版,基于『约定优于配置』的原则,快速开发出web程序. 环境 本系列笔记环境如下: Sun JDK1.8.0_20 ...

  5. 《设计模式之禅》--设计模式大PK

    创建类模式包括工厂方法模式.建造者模式.抽象工厂模式.单例模式和原型模式. 其中单例模式要保持在内存中只有一个对象,原型模式是要求通过复制的方式产生一个新的对象. [工厂方法(抽象工厂) VS 建造者 ...

  6. poj Hotel 线段树

    经典线段树的题. 每个节点存储的信息:左端点连续空房间的长度,右端点连续空房间长度,连续空房间的最大长度. 由于要求每次必须从尽量靠左边的位置进行居住,那么搜索时应尽量让区间起始位置更小: 1.如果当 ...

  7. Elasticsearch安装使用

    在网上有很多那种ES步骤和问题的解决 方案的,不过没有一个详细的整合,和问题的梳理:我就想着闲暇之余,来记录一下自己安装的过程以及碰到的问题和心得:有什么不对的和问题希望及时拍砖. 第一步:环境 li ...

  8. 我博客上的围棋js程序

    作为一个围棋爱好者,就决定在博客里加个围棋js程序.于是,申请了博客的js权限,美化美化我的博客. 好在js的语法像C系的,看了看,写个程序应该还是可以的. 围棋里,设计好基本的数据结构: //a是1 ...

  9. 高并发场景下的httpClient优化使用

    1.背景 我们有个业务,会调用其他部门提供的一个基于http的服务,日调用量在千万级别.使用了httpclient来完成业务.之前因为qps上不去,就看了一下业务代码,并做了一些优化,记录在这里. 先 ...

  10. Caffe可视化之VisualDL

    Visual DL是由 PaddlePaddle 和 ECharts 合作推出的一款深度学习可视化工具,其能够可视化scalar.参数分布.模型结构.图像等.底层采用C++编写,上层SDK以pytho ...