传送门

感觉要死在\(Splay\)里了 orz

这题用\(Splay\)维护这个序列,其中的第\(k\)大点代表这个序列的第\(k\)个数

第一个操作,先把那个数所在的点旋到根,然后把整个根的左子树接到右子树中最小的点,记得\(splay\)维护整棵树

第二个操作类似,把第一个操作反过来就行

第三个本质是两个相邻位置交换值,直接把这个数所在的点和前驱/后继交换值

第四个,把对应的点旋到根,输出左子树大小

第五个,就是整棵树的第\(x\)大点上的值

#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register using namespace std;
const int N=80000+10;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int n,q,b[N],p[N];
int fa[N],ch[N][2],sz[N],a[N],rt,tt;
il void psup(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;}
il void rot(int x)
{
int y=fa[x],z=fa[y],yy=ch[y][1]==x,w=ch[x][!yy];
ch[z][ch[z][1]==y]=x,fa[x]=z;
ch[y][yy]=w,fa[w]=y;
ch[x][!yy]=y,fa[y]=x;
psup(y),psup(x);
}
il void spl(int x,int en)
{
while(fa[x]!=en)
{
int y=fa[x],z=fa[y];
if(z!=en) ((ch[y][1]==x)^(ch[z][1]==y))?rot(x):rot(y);
rot(x);
}
if(!en) rt=x;
}
il void inst(int x)
{
int nw=rt;
while(ch[nw][x>a[nw]]) nw=ch[nw][x>a[nw]];
/*
++tt,fa[tt]=nw,a[tt]=x;
if(nw) ch[nw][x>a[nw]]=tt;
spl(tt,0);
*/
}
il int gkth(int x)
{
int nw=rt;
while(233)
{
if(x<=sz[ch[nw][0]]) nw=ch[nw][0];
else if(x>sz[ch[nw][0]]+1) x-=sz[ch[nw][0]]+1,nw=ch[nw][1];
else return nw;
}
}
il int bui(int l,int r)
{
if(l>r) return 0;
int mid=(l+r)>>1,nw=++tt;
a[nw]=b[mid],p[b[mid]]=nw,sz[nw]=1;
if(l==r) return nw;
fa[ch[nw][0]=bui(l,mid-1)]=nw;
fa[ch[nw][1]=bui(mid+1,r)]=nw;
psup(nw);
return nw;
} int main()
{
n=rd(),q=rd();
for(int i=1;i<=n;i++) b[i]=rd();
rt=bui(1,n);
char cc[10];
while(q--)
{
scanf("%s",cc);
if(cc[0]=='T')
{
int x=p[rd()];
spl(x,0);
if(!ch[x][0]);
else if(!ch[x][1]) swap(ch[x][0],ch[x][1]);
else
{
int y=gkth(sz[ch[x][0]]+2); //后继
ch[y][0]=ch[x][0],fa[ch[x][0]]=y,ch[x][0]=0;
spl(y,0);
}
}
else if(cc[0]=='B')
{
int x=p[rd()];
spl(x,0);
if(!ch[x][1]);
else if(!ch[x][0]) swap(ch[x][0],ch[x][1]);
else
{
int y=gkth(sz[ch[x][0]]); //前驱
ch[y][1]=ch[x][1],fa[ch[x][1]]=y,ch[x][1]=0;
spl(y,0);
}
}
else if(cc[0]=='I')
{
int x=p[rd()],c=rd();
if(c==1)
{
spl(x,0);
int nt=gkth(sz[ch[x][0]]+2); //主要是这个地方,我本来用普通平衡树里面的求前驱后继,但是这棵树并不是一个权值为关键字的splay,,,
swap(p[a[x]],p[a[nt]]),swap(a[x],a[nt]);
}
else if(c==-1)
{
spl(x,0);
int ft=gkth(sz[ch[x][0]]);
swap(p[a[x]],p[a[ft]]),swap(a[x],a[ft]);
}
}
else if(cc[0]=='A')
{
int x=p[rd()];
spl(x,0);
printf("%d\n",sz[ch[x][0]]);
}
else printf("%d\n",a[gkth(rd())]);
}
return 0;
}

luogu P2596 [ZJOI2006]书架的更多相关文章

  1. fhq_treap || BZOJ1861: [Zjoi2006]Book 书架 || Luogu P2596 [ZJOI2006]书架

    题面:P2596 [ZJOI2006]书架 题解:记录每本书对应的节点编号 普通fhq_treap无法查询一个权值的排名,所以在普通fhq_treap上多记录每个节点的父亲(可加在pushup函数中) ...

  2. 洛谷 P2596 [ZJOI2006]书架 解题报告

    P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...

  3. P2596 [ZJOI2006]书架 && Splay 区间操作(三)

    P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...

  4. [Luogu 2596] ZJOI2006 书架

    [Luogu 2596] ZJOI2006 书架 第一次指针写 FHQ_Treap(省选噩梦数据结构)AC 啦! 省选试机写它,紧张过度失败了. 省选 Day 1 考场写它,写挂了. 省选 Day 1 ...

  5. P2596 [ZJOI2006]书架(splay)

    [题目链接] https://www.luogu.org/problemnew/show/P2596 平衡树,需支持五个操作: 1. 将某元素置顶:将元素旋到根,然后将左子树合并到该元素的后继 2. ...

  6. [洛谷P2596] [ZJOI2006]书架

    洛谷题目链接:书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后 ...

  7. P2596 [ZJOI2006]书架

    思路 一开始写fhq-treap 感觉越写越感觉splay好些,就去splay 然后维护序列 注意前驱后继的不存在的情况 但不用插入虚拟节点(那插入岂不太麻烦) 跑的真慢的一批,splay太多了 错误 ...

  8. 洛谷 P2596 [ZJOI2006]书架 (splay)

    题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本.由于这些 ...

  9. 「luogu2569」[ZJOI2006] 书架

    「luogu2569」[ZJOI2006]书架 题目大意 给定一个长度为 \(n\) 序列,序列中第 \(i\) 个元素有编号 \(a_i(a_i \in \Z \cap [1,n])\),需要支持五 ...

随机推荐

  1. python之pygal:掷一个骰子统计次数并以直方图形式显示

    源码如下: # pygal包:生成可缩放的矢量图形文件,可自适应不同尺寸的屏幕显示 # 安装:python -m pip intall pygal-2.4.0-py2.py3-none-any.whl ...

  2. Gulp实现静态网页模块化的方法详解

    前言: 在做纯静态页面开发的过程中,难免会遇到一些的尴尬问题.比如:整套代码有50个页面,其中有40个页面顶部和底部模块相同.那么同样的两段代码我们复制了40遍(最难受的方法).然后,这个问题就这样解 ...

  3. 最大获利 HYSBZ - 1497 (最大权闭合图)

    最大权闭合图: 有向图,每个点有点权,点权可正可负.对于任意一条有向边i和j,选择了点i就必须选择点j,你需要选择一些点使得得到权值最大. 解决方法: 网络流 对于任意点i,如果i权值为正,s向i连容 ...

  4. python3.5 opencv3显示视频fps

    由于要进行多路视频的处理,所以fps就很重要 fps介绍 模板: 1.获取某一时刻的fps import time while True: start_time = time.time() # sta ...

  5. Hdoj 2187.悼念512汶川大地震遇难同胞——老人是真饿了 题解

    时间:2008年5月16日(震后第4天) 地点:汶川县牛脑寨 人物:羌族老奶奶 [转载整理]牛脑寨是一个全村600多人的羌族寨子,震后几天,这里依然能常常听到隆隆的声音,那是对面山上石头不断滑落的声音 ...

  6. 通过 powershell 配置 IIS

    1. 设置iis pool: cls Import-Module WebAdministration Get-ChildItem IIS:\apppools | ForEach-Object{     ...

  7. Mysql distinct、group by

    具体业务场景:根据某些字段组合去重得到所有字段结果. 遇到的error:sql_mode=only_full_group_by. 原因是mysql配置问题. distinct: distinct这个关 ...

  8. 使用debootstrap制作debian-jessie系统docker镜像

    先看一下Docker官网提示:In general, you'll want to start with a working machine that is running the distribut ...

  9. Windows 10更新时出现0x80070422错误

    Windows更新 更新状态 安装更新时出现一些问题,但我们稍后会重试.如果你继续看到此错误,并想要搜索Web或联系支持人员以获取相关信息,一下信息可能会对你有帮助:(0x80070422) 分析原因 ...

  10. CF1043

    找个下午打了场CF,结果被某uranus吊打......一千多名,过弱. T1,一眼二分了,后来发现题解是O(1)的hhh T2,题意精炼一下就是让你找一个串的循环节个数,直接n²枚举..... T3 ...