luogu P2596 [ZJOI2006]书架
感觉要死在\(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]书架的更多相关文章
- fhq_treap || BZOJ1861: [Zjoi2006]Book 书架 || Luogu P2596 [ZJOI2006]书架
题面:P2596 [ZJOI2006]书架 题解:记录每本书对应的节点编号 普通fhq_treap无法查询一个权值的排名,所以在普通fhq_treap上多记录每个节点的父亲(可加在pushup函数中) ...
- 洛谷 P2596 [ZJOI2006]书架 解题报告
P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...
- P2596 [ZJOI2006]书架 && Splay 区间操作(三)
P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...
- [Luogu 2596] ZJOI2006 书架
[Luogu 2596] ZJOI2006 书架 第一次指针写 FHQ_Treap(省选噩梦数据结构)AC 啦! 省选试机写它,紧张过度失败了. 省选 Day 1 考场写它,写挂了. 省选 Day 1 ...
- P2596 [ZJOI2006]书架(splay)
[题目链接] https://www.luogu.org/problemnew/show/P2596 平衡树,需支持五个操作: 1. 将某元素置顶:将元素旋到根,然后将左子树合并到该元素的后继 2. ...
- [洛谷P2596] [ZJOI2006]书架
洛谷题目链接:书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后 ...
- P2596 [ZJOI2006]书架
思路 一开始写fhq-treap 感觉越写越感觉splay好些,就去splay 然后维护序列 注意前驱后继的不存在的情况 但不用插入虚拟节点(那插入岂不太麻烦) 跑的真慢的一批,splay太多了 错误 ...
- 洛谷 P2596 [ZJOI2006]书架 (splay)
题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本.由于这些 ...
- 「luogu2569」[ZJOI2006] 书架
「luogu2569」[ZJOI2006]书架 题目大意 给定一个长度为 \(n\) 序列,序列中第 \(i\) 个元素有编号 \(a_i(a_i \in \Z \cap [1,n])\),需要支持五 ...
随机推荐
- 【转】SpringMVC,获取request的几种方法,及线程安全性
作者丨编程迷思 https://www.cnblogs.com/kismetv/p/8757260.html 概述 在使用Spring MVC开发Web系统时,经常需要在处理请求时使用request对 ...
- python之time模块:获取当前时间
time模块举例 import time # 获取当前时间戳 t = time.time() print('1)获取当前时间戳:', t) # 当前时间的struct_time形式 t = time. ...
- codeforces 1051 D. Bicolorings (DP)
D. Bicolorings time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...
- 优步加入Linux基金会:支持开源
导读 当地时间11月16日,优步在Uber Open Summit 2018年度峰会上宣布加入Linux基金会,并作为金级会员坚定支持对开源工具的使用和贡献. 优步CEO Thuan Pham将Lin ...
- 我的G++编译选项
-Wall -Wextra -g3 -DLOCAL -Wshadow -Wpointer-arith -Wcast-qual -Waggregate-return -Winline -Wunreach ...
- Java 入门进阶
Java 入门进阶 發表於 2015-04-16 http://xielong.me/2015/04/16/%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%B7%A5%E7%A8%8B% ...
- mysql 免安装版 启动服务马上关闭
在my.ini 加入这一句 1.直接在后面加上一下的参数 [mysqld] port=3306 basedir=D:\mysql-5.7.17-win32 datadir=D:\mysql-5.7.1 ...
- 【转】hex和bin文件格式的区别
hex和bin文件格式的区别 Intel HEX文件是记录文本行的ASCII文本文件,在Intel HEX文件中,每一行是一个HEX记录,由十六进制数组成的机器码或者数据常量.Intel HEX文件经 ...
- php关于Session和cookie总结
什么是 Cookie? cookie 常用于识别用户.cookie 是服务器留在用户计算机中的小文件.每当相同的计算机通过浏览器请求页面时,它同时会发送 cookie.通过 PHP,能够创建并取回 c ...
- 【LOJ#10002】喷水装置
题目大意:给定一段区间 [l,r] ,N 条线段,求至少用多少条线段能够覆盖整个区间,不能覆盖输出-1. 题解:每次在起点小于当前位置的线段集合中选择有端点最大的位置作为下一个位置,并更新答案,如果当 ...