小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. php红包算法函数[优化]

    php红包算法 <?php header("Content-Type: text/html;charset=utf-8");//输出不乱码,你懂的 $total=10000; ...

  2. 【linux】【指令】systemctl 指令部分解读

    systemctl [OPTIONS...] {COMMAND} ... Query or send control commands to the systemd manager. -h --hel ...

  3. PHP Socket服务器搭建和测试

    1.socket服务器搭建思路 1) 目的:理解socket服务器工作机制 2) 思路:创建socket -> 把socket加入连接池 -> 处理接收信息 -> 握手动作 -> ...

  4. Python 对象(type/object/class) 作用域 一等函数 (慕课--Python高级,IO并发 第二章)

    在python中一共有两种作用域:全局作用域和函数作用域全局作用域:在全局都有效,全局作用域在程序执行时创建,在程序执行结束时销毁:所有函数以外的区域都是全局作用域:在全局作用域中定义的变量,都属于全 ...

  5. 霍夫圆检测 opencv

    进行霍夫圆变换中有一个API:HoughCircles(). 第五个参数为double类型的minDist(),为霍夫变换检测到的圆的圆心之间的最小距离,即让算法能明显区分的两个不同圆之间的最小距离. ...

  6. C# 输出结果有System.Byte[]

    byte[]类型直接输出或者调用ToString函数都会出现这个结果. 需要执行: byte[] a=new byte[10]; string text = "";for (int ...

  7. scrapy如何实现分布式爬虫

    使用scrapy爬虫的时候,记录一下如何分布式爬虫问题: 关键在于多台主机协作的关键:共享爬虫队列 主机:维护爬取队列从机:负责数据抓取,数据处理,数据存储 队列如何维护:Redis队列Redis 非 ...

  8. 13,SQLAlchemy 增删改查 一对多 多对多

    今天来聊一聊 Python 的 ORM 框架 SQLAlchemy Models 是配置和使用比较简单,因为他是Django自带的ORM框架,也正是因为是Django原生的,所以兼容性远远不如SQLA ...

  9. CodeForces 805F Expected diameter of a tree 期望

    题意: 给出一个森林,有若干询问\(u, v\): 从\(u, v\)中所在子树中随机各选一个点连起来,构成一棵新树,求新树直径的期望. 分析: 回顾一下和树的直径有关的东西: 求树的直径 从树的任意 ...

  10. 《Cracking the Coding Interview》——第9章:递归和动态规划——题目11

    2014-03-21 20:20 题目:给定一个只包含‘0’.‘1’.‘|’.‘&’.‘^’的布尔表达式,和一个期望的结果(0或者1).如果允许你用自由地给这个表达式加括号来控制运算的顺序,问 ...