洛谷.2596.[ZJOI2006]书架(Splay)
/*
五个操作:
1.将某元素置顶。删掉这个数,插入最左
2.将某元素置底。同样
3.旋到根后,直接将这个数与前驱/后继交换所有信息 不是左右子节点!
4.5.裸平衡树
ps:1.用pos[i]表示第i本书在树上对应的节点,会方便很多(虽然复杂的我也不会)。注意比较的是pos,再开个数组
2.交换信息交换记录有用信息的pos和t即可。注意pos是t值的位置,换的是pos[tx],pos[ty]
3.pos[v]即v现在的位置,平衡树中正是以下标位置为排序标准的。将v旋到根即Splay(pos[v],root)
4.找前驱可以直接return Rank(sz[x]-1),后继同理
5.删除节点可以利用该节点的排名,将前驱旋到根上,后继旋到son[root][1],就可以直接删掉这个点
6.加入两个哨兵节点 操作1.2就会非常容易
不明白Move中Bottom为什么是找第n和n+1...
*/
#include<cstdio>
#include<cctype>
#include<algorithm>
#define gc() getchar()
const int N=8e4+5;
int n,m,root,pos[N],t[N],sz[N],son[N][2],fa[N];
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
inline void Update(int rt)
{
sz[rt]=sz[son[rt][0]]+sz[son[rt][1]]+1;
}
void Build(int l,int r,int f)
{
if(l>r) return;
int m=l+r>>1;
fa[m]=f, son[f][m>f]=m, sz[m]=1;
if(l==r) return;
Build(l,m-1,m), Build(m+1,r,m);
Update(m);
}
void Rotate(int x,int &k)
{
int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
if(a==k) k=x;
else son[b][son[b][1]==a]=x;
fa[x]=b, fa[a]=x, fa[son[x][r]]=a;
son[a][l]=son[x][r], son[x][r]=a;
Update(a), Update(x);
}
void Splay(int x,int &k)
{
while(x!=k)
{
int a=fa[x],b=fa[a];
if(a!=k) (son[a][1]==x^son[b][1]==a)?Rotate(x,k):Rotate(a,k);
Rotate(x,k);
}
}
int Rank(int v,int k)
{
while(1)
{
if(sz[son[k][0]]+1==v) return k;
if(sz[son[k][0]]>=v) k=son[k][0];
else v-=sz[son[k][0]]+1,k=son[k][1];
}
}
//void Delete(int v)
//{
// int k=root;
// if(son[k][0]&&son[k][1])
// {
// int p=son[k][0];root=k=son[k][1];
// while(son[k][0]) k=son[k][0];
// fa[p]=k, son[k][0]=p, sz[k]+=sz[p];
// Splay(k,root);
// }
// else root=son[k][0]|son[k][1];
// fa[root]=0;
//}
void Delete(int k)
{
int a=Rank(k-1,root),b=Rank(k+1,root);
Splay(a,root), Splay(b,son[a][1]);
fa[son[b][0]]=sz[son[b][0]]=0, son[b][0]=0;
Update(b), Update(a);
}
void Move(int x,int v)
{
Splay(x,root);
int rank=sz[son[x][0]]+1;
Delete(rank);
int a,b;
if(v==N) a=Rank(1,root),b=Rank(2,root);
else if(v==-N) a=Rank(n,root),b=Rank(n+1,root);//n+1 n+2?
// else a=Rank(rank+v-1,root),b=Rank(rank+v,root);
Splay(a,root),Splay(b,son[a][1]);
sz[x]=1, fa[x]=b, son[b][0]=x;
Update(b), Update(a);
}
void Swap(int x,int y,int w)
{
while(son[y][w]) y=son[y][w];
std::swap(t[x],t[y]);
std::swap(pos[t[x]],pos[t[y]]);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("2596.in","r",stdin);
#endif
n=read(),m=read();
for(int i=2;i<=n+1;++i) t[i]=read(),pos[t[i]]=i;
Build(1,n+2,0);//Print(1+n>>1),putchar('\n');
root=3+n>>1;
char s[10];int v,k,p,x;
while(m--)
{
scanf("%s",s),v=read();
if(s[0]=='T')
{
Move(pos[v],N);
// WA: v=pos[v], Splay(v,root), p=root, Delete(v);
// x=root;
// while(son[x][0]) x=son[x][0];
// fa[p]=x, son[p][0]=son[p][1]=0, sz[p]=1;
// son[x][0]=p, ++sz[x];
// Splay(x,root);
}
else if(s[0]=='B')
{
Move(pos[v],-N);
// WA: v=pos[v], Splay(v,root), p=root, Delete(v);
// x=root;
// while(son[x][1]) x=son[x][1];
// fa[p]=x, son[p][0]=son[p][1]=0, sz[p]=1;
// son[x][1]=p, ++sz[x];
// Splay(x,root);
}
else if(s[0]=='I')
{
// k=read(), Move(pos[v],k);
k=read(), Splay(pos[v],root);
if(k==-1) Swap(root,son[root][0],1);
else if(k==1) Swap(root,son[root][1],0);
}
else if(s[0]=='A') Splay(pos[v],root),printf("%d\n",sz[son[root][0]]-1);
else printf("%d\n",t[Rank(v+1,root)]);
}
return 0;
}
洛谷.2596.[ZJOI2006]书架(Splay)的更多相关文章
- 洛谷 P2596 [ZJOI2006]书架 (splay)
题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本.由于这些 ...
- [洛谷P2596] [ZJOI2006]书架
洛谷题目链接:书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后 ...
- 洛谷 P2596 [ZJOI2006]书架 解题报告
P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...
- [Luogu 2596] ZJOI2006 书架
[Luogu 2596] ZJOI2006 书架 第一次指针写 FHQ_Treap(省选噩梦数据结构)AC 啦! 省选试机写它,紧张过度失败了. 省选 Day 1 考场写它,写挂了. 省选 Day 1 ...
- BZOJ3224/洛谷P3391 - 普通平衡树(Splay)
BZOJ链接 洛谷链接 题意简述 模板题啦~ 代码 //普通平衡树(Splay) #include <cstdio> int const N=1e5+10; int rt,ndCnt; i ...
- P2596 [ZJOI2006]书架 && Splay 区间操作(三)
P2596 [ZJOI2006]书架 题目描述 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书, ...
- [洛谷P3391] 文艺平衡树 (Splay模板)
初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...
- [洛谷P2584][ZJOI2006]GameZ游戏排名系统
题目大意:同[洛谷P4291][HAOI2008]排名系统(双倍经验) 题解:略 卡点:无 C++ Code: #include <cstdio> #include <map> ...
- BZOJ1861:[ZJOI2006]书架(Splay)
Description 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下 ...
随机推荐
- NMS和soft-nms算法
非极大值抑制算法(nms) 1. 算法原理 非极大值抑制算法(Non-maximum suppression, NMS)的本质是搜索局部极大值,抑制非极大值元素. 2. 3邻域情况下NMS的实现 3邻 ...
- android camera(一):camera模组CMM介绍【转】
转自:https://blog.csdn.net/kevinx_xu/article/details/8821818 androidcmm图像处理工作手机三星 关键词:android camera ...
- AWTK(Toolkit AnyWhere): 为嵌入式、手机和桌面开发的通用GUI【转】
转自:https://blog.csdn.net/absurd/article/details/80958279 AWTK = Toolkit AnyWhere AWTK是吸取了FTK和CanTK的精 ...
- zabbix3.0.4使用shell脚本和zabbix自带模板两种方法添加对指定进程和端口的监控
zabbix3.0.4添加对进程的监控: 方法一:通过自定义命令进行监控 主要思路: 通过 ps -ef|grep sdk-push-1.0.0.jar |grep -v grep|wc -l 这个命 ...
- Expm 7_1树中的最大独立集问题
[问题描述] 给定一个无回路的无向图(即树),设计一个动态规划算法,求出该图的最大独立集,并输出该集合中的各个顶点值. package org.xiu68.exp.exp7; import java. ...
- MyCP(课下作业,必做)
作业要求 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt XXX2.bin 用来把文本文件(内容为 ...
- Eclipse通过jdbc连接sqlserver2008数据库的两种方式
数据库登录身份验证方式有两种 其中服务器名称即为安装SQLServer2008的电脑,充当数据库服务器,在笔者这里就是自己的电脑名称. 身份验证方式有两种:windows身份验证和SQLSer ...
- mysql8.0CTE实现递归查询
+----+----------+--------------+| ID | ParentID | name |+----+----------+--------------+| 1 ...
- Storm的部署
配置方案如下 node1 Nimbus zookeeper node2 Supervisor zookeeper node3 Supervisor zookeeper node4 Supervisor ...
- LeetCode(41):缺失的第一个正数
Hard! 题目描述: 给定一个未排序的整数数组,找出其中没有出现的最小的正整数. 示例 1: 输入: [1,2,0] 输出: 3 示例 2: 输入: [3,4,-1,1] 输出: 2 示例 3: 输 ...