洛谷.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在看书的时候,每次取出一本书,看完后放回书柜然后再拿下 ...
随机推荐
- 【转】Python之数据序列化(json、pickle、shelve)
[转]Python之数据序列化(json.pickle.shelve) 本节内容 前言 json模块 pickle模块 shelve模块 总结 一.前言 1. 现实需求 每种编程语言都有各自的数据类型 ...
- 在imagenet预训模型上进行finetune
所谓fine tune就是用别人训练好的模型,加上我们自己的数据,来训练新的模型.fine tune相当于使用别人的模型的前几层,来提取浅层特征,然后在最后再落入我们自己的分类中. fine tune ...
- Linux的capability深入分析(2)【转】
转自:https://blog.csdn.net/wangpengqi/article/details/9821231 rpm -ql libcap-2.16-5.2.el6.i686 /lib/l ...
- n个随机变量中第k小值的期望
Problem 有\(n\)个相互独立的取值在\([0,1]\)的随机变量,问其中第\(k\)小的变量期望是多少? Solution 之前pkuwc的神仙找我换友链,让我受宠若惊.. 我今天突然翻到他 ...
- 017_mac格式化硬盘,mac如何格式化硬盘
想做一个mac和windows都能识别的系统,推荐设置成什么格式 一.在mac下格式化 在Mac 下,打开右下角应用程序-实用工具-磁盘工具,里面选取你的移动硬盘,然后进行格式化,设置成EXFat格式 ...
- WDS 三种模式
(1)懒人模式(Lazy mode) 此模式下不需要填写对端的BSSID,本端AP的WDS连接作为被动连接,只需要对端填写了本端AP的BSSID即可,效果和桥接模式一样. (2)桥接模式(Bridge ...
- SQL代码整理
--SQL代码整理: create database mingzi--创建数据库go--连接符(可省略)create table biao--创建表( lieming1 int not null,-- ...
- Java char
Java char字符判断和操作方法类似C的ctype库 //: object/Shifting.java package object; import static net.util.Print. ...
- composer 安装依赖缓慢,查看 composer 的详细执行日志
在 windows WSL 上安装 composer 依赖 composer install 发现执行异常缓慢,怀疑没有走国内的镜像,而是直接访问的 github. 需要能看到 composer 的执 ...
- iOS学习笔记之UITableViewController&UITableView
iOS学习笔记之UITableViewController&UITableView 写在前面 上个月末到现在一直都在忙实验室的事情,与导师讨论之后,发现目前在实验室完成的工作还不足以写成毕业论 ...