小T有一个很大的书柜。这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列。她用1到n的正整数给每本书都编了号。 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本。由于这些书太有吸引力了,所以她看完后常常会忘记原来是放在书柜的什么位置。不过小T的记忆力是非常好的,所以每次放书的时候至少能够将那本书放在拿出来时的位置附近,比如说她拿的时候这本书上面有X本书,那么放回去时这本书上面就只可能有X-1、X或X+1本书。 当然也有特殊情况,比如在看书的时候突然电话响了或者有朋友来访。这时候粗心的小T会随手把书放在书柜里所有书的最上面或者最下面,然后转身离开。 久而久之,小T的书柜里的书的顺序就会越来越乱,找到特定的编号的书就变得越来越困难。于是她想请你帮她编写一个图书管理程序,处理她看书时的一些操作,以及回答她的两个提问:(1)编号为X的书在书柜的什么位置;(2)从上到下第i本书的编号是多少。

Input

第一行有两个数n,m,分别表示书的个数以及命令的条数;第二行为n个正整数:第i个数表示初始时从上至下第i个位置放置的书的编号;第三行到m+2行,每行一条命令。命令有5种形式: 1. Top S——表示把编号为S的书房在最上面。 2. Bottom S——表示把编号为S的书房在最下面。 3. Insert S T——T∈{-1,0,1},若编号为S的书上面有X本书,则这条命令表示把这本书放回去后它的上面有X+T本书; 4. Ask S——询问编号为S的书的上面目前有多少本书。 5. Query S——询问从上面数起的第S本书的编号。

Output

对于每一条Ask或Query语句你应该输出一行,一个数,代表询问的答案。

Sample Input

10 10
1 3 2 7 5 8 10 4 9 6
Query 3
Top 5
Ask 6
Bottom 3
Ask 3
Top 6
Insert 4 –1
Query 5
Query 2
Ask 2

Sample Output

2
9
9
7
5
3
数据范围
30%的数据,n,m < = 10000
100%的数据,n,m < = 80000

这是一道splay的模板题,算是入门了吧,毕竟不会所有平衡树,过会得开一讲了,
这道题就是裸的splay,真的比较水,整理的是hzwer大佬的模板,注释在代码上来。
 #include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring> using namespace std; const int NN=,inf=1e9+; int n,m,rt,sz;
int c[NN][],fa[NN],deep[NN];
int a[NN],size[NN],v[NN],pos[NN]; void update(int k)//仅仅用来得到k的大小
{
size[k]=size[c[k][]]+size[c[k][]]+;
}
void rotate(int x,int &k)//一次旋转
{
int y=fa[x],z=fa[y],l,r;
if (c[y][]==x) l=;
else l=;
r=l^;
if (y==k) k=x;
else if (c[z][]==y) c[z][]=x;
else c[z][]=x;
fa[x]=z,fa[y]=x,fa[c[x][r]]=y;
c[y][l]=c[x][r],c[x][r]=y;
update(y),update(x);//普通的一次操作。
}
void splay(int x,int &k)
{
while(x!=k)
{
int y=fa[x],z=fa[y];
if (y!=k)
{
if (c[y][]==x^c[z][]==y)//这个是判断zig还是zag,来决定谁先交换。
rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
void build(int l,int r,int f)//l,r是表示区间,f表示根
{
if (l>r) return;
int now=l,last=f;
if (l==r)
{
v[now]=a[l],size[now]=,fa[now]=last;
if (l<f) c[last][]=now;//右边左边的问题
else c[last][]=now;
return;
}
int mid=(l+r)>>;
now=mid;
build(l,mid-,mid);build(mid+,r,mid);
v[now]=a[mid],fa[now]=last;
update(now);
if (mid<f) c[last][]=now;
else c[last][]=now;
}
int find(int k,int rank)//以k为根的树中找rank
{
int l=c[k][],r=c[k][];
if (size[l]+==rank) return k;
else if (size[l]>=rank) return find(l,rank);
else return find(r,rank-size[l]-);
}
void del(int k)
{
int x,y,z;
x=find(rt,k-),y=find(rt,k+);
splay(x,rt),splay(y,c[x][]);
z=c[y][],c[y][]=,fa[z]=size[z]=;//把前驱转到根,把后驱转到根右子树,然后根右子树左儿子就是要删除的值。
update(y),update(x);
}
void move(int k,int val)//就是将编号为k的放到val值的地方。
{
int x,y,z=pos[k],rank;
splay(z,rt);
rank=size[c[z][]]+;
del(rank);
if (val==inf) x=find(rt,n),y=find(rt,n+);
else if (val==-inf) x=find(rt,),y=find(rt,);
else x=find(rt,rank+val-),y=find(rt,rank+val);
splay(x,rt),splay(y,c[x][]);
size[z]=,fa[z]=y,c[y][]=z;
update(y),update(x);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n+;i++)//特别把1空出来,防止越界。
{
scanf("%d",&a[i]);
pos[a[i]]=i;//反向映射。
}
build(,n+,);
rt=(+n)>>;
char ch[];int S,T;
for (int i=;i<=m;i++)
{
scanf("%s%d",ch,&S);
switch(ch[])
{
case'T':move(S,-inf);break;
case'B':move(S,inf);break;
case'I':scanf("%d",&T);move(S,T);break;
case'A':splay(pos[S],rt);printf("%d\n",size[c[pos[S]][]]-);break;
case'Q':printf("%d\n",v[find(rt,S+)]);break;
}
}
}

bzoj1861 [Zjoi2006]Book 书架 splay的更多相关文章

  1. bzoj1861 [Zjoi2006]Book 书架——splay

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1861 发现自己想splay的时候总是纠结那个点权是什么,因为splay原本是二分查找树... ...

  2. [BZOJ1861][Zjoi2006]Book 书架

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

  3. [bzoj1861][Zjoi2006]Book 书架_非旋转Treap

    Book 书架 bzoj-1861 Zjoi-2006 题目大意:给你一个序列,支持:将指定编号的元素抽出,放到序列顶(底):将指定编号元素左右篡位:查询指定编号元素位置:查询指定数量位置元素编号. ...

  4. BZOJ 1861: [Zjoi2006]Book 书架 splay

    1861: [Zjoi2006]Book 书架 Description 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书 ...

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

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

  6. BZOJ 1861: [Zjoi2006]Book 书架 | SPlay 板题

    #include<cstdio> #include<algorithm> #include<cstring> #define N 80010 #define whi ...

  7. BZOJ 1861 [Zjoi2006]Book 书架 ——Splay

    [题目分析] 模板题目. 首尾两个虚拟结点,十分方便操作. [代码] #include <cstdio> #include <cstring> #include <cma ...

  8. 并不对劲的bzoj1861: [Zjoi2006]Book 书架

    传送门-> 这题的正确做法是splay维护这摞书. 但是并不对劲的人选择了暴力(皮这一下很开心). #include<algorithm> #include<cmath> ...

  9. BZOJ1861[ZJOI2006]Book书架

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

随机推荐

  1. SpringBoot注入Mapper提示Could not autowire. No beans of 'xxxMapper' type found错误

    通过用Mabatis的逆向工程生成的Entity和Mapper.在Service层注入的时候一直提示Could not autowire. No beans of 'xxxMapper' type f ...

  2. 【转载】谈MongoDB的应用场景

    引用:http://blog.csdn.net/adparking/article/details/38727911 MongoDB的应用场景在网上搜索了下,很少介绍关于传统的信息化应用中如何使用Mo ...

  3. C# 打开帮助文档,打开电脑中其他应用或者文件

    打开帮助文档 System.Diagnostics.Process.Start(Directory.GetCurrentDirectory() + "\\" + "hel ...

  4. dijkstra算法与优先队列

    这是鄙人的第一篇技术博客,作为算法小菜鸟外加轻度写作障碍者,写技术博客也算是对自己的一种挑战和鞭策吧~ 言归正传,什么是dijkstra算法呢? -dijkstra算法是一种解决最短路径问题的简单有效 ...

  5. 集合源码分析之 HashSet

    一 知识准备 HashSet 是Set接口的实现类,Set存在的最大意义区别于List就是,Set中存放的元素不能够重复,就是不能够有两个相同的元素存放在Set中,那么怎样的两个元素才算是相同的,这里 ...

  6. jquery跨域解决方案JSONP

    1.在互联网中我们的计算机是通过IP来定位的,但是IP比较难记忆,因此通过domain name(域名)来取代IP 2.什么是跨域? (1)默认浏览器为了安全问题,禁止了xmlhttprequest跨 ...

  7. Column 'sort' specified twice错误

    我使用的是mybatis框架出现的这个问题,如果你们也出现了这个问题的豪华,我想你们的sql代码一定是复制的吧,额哈哈哈

  8. 分布式缓存技术memcached学习系列(一)——linux环境下编译memcahed

    安装依赖工具 [root@localhost upload]# yum  install gcc  make  cmake  autoconf  libtool 下载并上传文件 memcached 依 ...

  9. 《数据结构与算法分析:C语言描述》复习——第九章“图论”——拓扑排序

    2014.07.04 17:23 简介: 我们考虑一种特殊的图: 1. 有向图 2. 只有一个连通分量 3. 不存在环 那么这样的图里,必然可以找到一种排序方式,来确定谁在谁的“前面”. 简单的来说可 ...

  10. adb启动和关闭

    启动adb服务: cmd("adb start-server"); 关闭adb服务: cmd("adb start-server");