题目描述

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

输入

第一行有两个数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本书的编号。

输出

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

样例输入

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

样例输出

2 9 9 7 5 3

提示

 30%的数据,n,m<=10000
100%的数据,n,m<=80000
 
题解:
关键是开一个*id[i]保存编号为i的书所在节点的编号,然后在newnode的时候更新他的位置
题目中
Insert就是交换id[x]和他的前驱的id的值,然后再换节点对应的编号.
Bottom就是删掉该节点,在把它的位置改成maxn+1(使得他的编号比任何一个节点都大,就达到了放在底端的效果),maxn表示当前最大的编号,并把maxn++.Top同理
Query就是把x转到根,然后答案就是左子节点的size
Ask 就是排名为k的数
然后就开始乱搞
我犯的低级错误:
1.insert y=0时没特判
2.把第一个数放在顶端也没特判
代码如下:
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<ctime>
using namespace std;
const int N=,INF=;
struct node
{
int x,size,book;
node *child[],*fa;
}a[N*];
node *pos=a,*root,*id[N];
void newnode(node *&r,int key,node *ff,int number)
{
r=pos++;
r->size=,id[number]=r;
r->x=key;r->fa=ff;r->book=number;
r->child[]=r->child[]=NULL;
}
int gi()
{
int str=;char ch=getchar();
while(ch>'' || ch<'')ch=getchar();
while(ch>=''&& ch<='')str=str*+ch-'',ch=getchar();
return str;
}
int n,m;
void updata(node *&r)
{
if(r){
r->size=(r->child[]?r->child[]->size:)+(r->child[]?r->child[]->size:)+;
return ;
}
}
void rotate(node *&r,bool t)
{
node *y=r->fa;
y->child[!t]=r->child[t];
if(r->child[t])r->child[t]->fa=y;
r->fa=y->fa;
if(y->fa)y->fa->child[y->fa->child[]==y]=r;
r->child[t]=y;
y->fa=r;
updata(y);
updata(r);
updata(r->fa);
}
void splay(node *r,node *g)
{
while(r->fa!=g)
{
if(r->fa->fa==g)rotate(r,r->fa->child[]==r);
else{
node *y=r->fa;
bool t=y->fa->child[]==y;
if(y->child[t]==r)rotate(r,!t);
else rotate(y,t);
rotate(r,t);
}
}
if(g==NULL)root=r;
}
void insert(node *&r,int key,node *fa,int number)
{
if(r==NULL){
newnode(r,key,fa,number);
splay(r,NULL);
return;
}
else insert(r->child[key>r->x],key,r,number);
}
node *pre,*nxt;
char s[];
void getpre(node *r,int key)
{
if(!r)return ;
if(r->x>=key)getpre(r->child[],key);
else pre=r,getpre(r->child[],key);
}
void getnext(node *r,int key)
{
if(!r)return ;
if(r->x<=key)getnext(r->child[],key);
else nxt=r,getnext(r->child[],key);
}
void Ask(int x)
{
splay(id[x],NULL);
printf("%d\n",root->child[]?root->child[]->size:);
return ;
}
int getrank(node *r,int rk)
{
while(r){
int d=r->child[]?r->child[]->size:;
if(rk==d+)return r->book;
if(rk<d+)r=r->child[];
else rk-=d+,r=r->child[];
}
return -;
}
node *findmax(node *r)
{
if(r->child[])return findmax(r->child[]);
else return r;
}
int maxn=,minn=;
void Delet(int x)
{
node *y;
splay(id[x],NULL);
if(root->child[]){
y=findmax(root->child[]);
splay(y,root);
y->child[]=root->child[];
y->fa=NULL;
if(root->child[])
root->child[]->fa=y;
root=y;
updata(y);
}
else{
root=root->child[];
root->fa=NULL;
}
}
void Totop(int x,bool t)
{
Delet(x);
if(!t)
insert(root,--minn,NULL,x);
else
insert(root,++maxn,NULL,x);
}
void change(int x,int y)
{
node *kl;
if(y==)getnext(root,id[x]->x),kl=nxt;
else getpre(root,id[x]->x),kl=pre;
y=kl->book;
swap(id[x],id[y]);
swap(id[x]->book,id[y]->book);
}
int main()
{
int x,y;
n=gi();m=gi();maxn=n;
for(int i=;i<=n;i++){
x=gi();
insert(root,i,NULL,x);
}
int cc=;
while(m--){
scanf("%s%d",s,&x);
if(s[]=='A')Ask(x);
else if(s[]=='Q')printf("%d\n",getrank(root,x));
else if(s[]=='I'){scanf("%d",&y);if(y)change(x,y);}
else if(s[]=='T')Totop(x,);
else if(s[]=='B')Totop(x,);
}
return ;
}

[LSGDOJ1822]书架 Splay的更多相关文章

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

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

  2. BZOJ-1861 Book 书架 Splay

    1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec Memory Limit: 64 MB Submit: 1010 Solved: 588 [Submit][Stat ...

  3. [题解]bzoj 1861 Book 书架 - Splay

    1861: [Zjoi2006]Book 书架 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1396  Solved: 803[Submit][Stat ...

  4. P2596 [ZJOI2006]书架 && Splay 区间操作(三)

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

  5. 洛谷.2596.[ZJOI2006]书架(Splay)

    题目链接 /* 五个操作: 1.将某元素置顶.删掉这个数,插入最左 2.将某元素置底.同样 3.旋到根后,直接将这个数与前驱/后继交换所有信息 不是左右子节点! 4.5.裸平衡树 ps:1.用pos[ ...

  6. BZOJ1861:[ZJOI2006]书架(Splay)

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

  7. 洛谷 P2596 [ZJOI2006]书架 (splay)

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

  8. bzoj1861 书架 splay版

    单点插入删除以及求前缀 #include<cstdio> #include<cstring> #include<algorithm> using namespace ...

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

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

随机推荐

  1. 基于微信小程序的失物招领系统的Postmortem

    基于微信小程序的失物招领系统的Postmortem 设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 对于我们团队要解决的问题和实现的功能在项目开始就 ...

  2. jQuery函数学习

    函数:after(content) 功能:在每个匹配的元素后面添加html内容 返回:jQuery对象 参数:content (<Content>): Content to insert ...

  3. HTML,文字两端对齐

    text-align: justify样式的意思是文字两端对齐,但是有时候你会发现这东西不起左右,比如在div标签中的文字. 解决方法:在div中放一个空的span标签,并使用下面的样式. .just ...

  4. Oracle闪回技术

    (一)闪回技术概要 闪回技术是数据库备份与恢复的重要补充手段,主要包括以下7种特性: 特性 原理 数据库支持 闪回查询(Flashback Query) 利用undo表空间中的回退信息,查询过去某个时 ...

  5. NATAPP 内网映射,Visual Studio ,C# 实现本地开发微信公众号,本地调试无需服务器

    点击软件安装教程,根据安装教程,注册帐号,下载软件,配置软件.配置完后如下图,途中红色位置免费版本是随机的. 红色位置是自己的映射域名. 打开VS,并且打开项目,右键项目,在web 选项中修改项目UR ...

  6. Ubuntu16.04 + Zabbix 3.4.7 邮件报警设置

    部署了Zabbix,需要配置邮件报警,在网上找了一些教程,大多是是用的CentOS + Zabbix 2.x版本的,而且还要写脚本,感觉太麻烦了,所以自己结合其他文章摸索了一套配置方法. 先说一下环境 ...

  7. Mego开发文档 - 数据注释建模

    数据注释建模 Mego框架使用一组约定来基于CLR类来构建模型.您可以指定其他配置来补充或覆盖通过约定发现的内容. 在 Mego 中所有的数据对象必须要有主键.这里需要声明与EF不同的是框架只支持数据 ...

  8. Docker加速器(阿里云)

    1. 登录阿里开发者平台: https://dev.aliyun.com/search.html,https://cr.console.aliyun.com/#/accelerator,生成专属链接 ...

  9. gradle入门(1-1)gradle的概念和使用

    一.Gradle是什么 Gradle是一种Java应用构建工具,它采用领域特定语言 Groovy 语法实现配置. 1.Gradle的基本概念 项目:项目的配置 即 build.gradle. 任务:任 ...

  10. matlab 对tif数据高程图的处理分析

    temp=z(101:2200,101:2200) 根据图像属性可得此为2300*2300的tif图像,由于需要将其划分为9宫格,所以begin点设置为101,end点设置为2200,temp转化为可 ...