1861: [Zjoi2006]Book 书架

Time Limit: 4 Sec Memory Limit: 64 MB

Submit: 1010 Solved: 588

[Submit][Status][Discuss]

Description

小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

HINT

数据范围

100%的数据,n,m < = 80000

Source

Day2

比较裸的Splay,无奈语文差一开始理解错意思了...

操作insert似乎意思是这样的…从他上面取下了书,放回去后放到他的下面,所以-1;从他上面取书又放在他上面,所以为0;没从上面取书,把书放在他上面所以+1;…..

总之 旋转+伸展(这TM不是废话吗..)+插入+删除+区间查询+单点查 询 即可维护

code(即本人splay模板…):

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath> using namespace std; const int N=80012;
int n,m,x,y,z;
char opt,ch;
struct Snode
{
Snode *lch,*rch,*p;
int id,size;
inline void update(){size=lch->size+rch->size+1;}
inline bool is_l() {return this==p->lch;}
inline void set_l(Snode *x) {lch=x;x->p=this;}
inline void set_r(Snode *x) {rch=x;x->p=this;}
inline void left()
{
Snode *fa=p;
if (fa->is_l()) fa->p->set_l(this);
else fa->p->set_r(this);
fa->set_r(lch);set_l(fa);fa->update();
}
inline void right()
{
Snode *fa=p;
if (fa->is_l()) fa->p->set_l(this);
else fa->p->set_r(this);
fa->set_l(rch);set_r(fa);fa->update();
}
inline Snode *rank(int k)
{
if (lch->size+1==k) return this;
if (lch->size+1<k) return rch->rank(k-lch->size-1);
else return lch->rank(k);
}
} T[2*N],*P=T,*nil=T,*root,*pos[N],*ld,*rd;
inline void newnode(Snode *&node,int x)
{
node=++P;
node->lch=node->rch=node->p=nil;
node->size=1;node->id=x;
}
inline void splay(Snode *&root,Snode *x,Snode *y)
{
while (x->p!=y)
{
if (x->p->p==y)
{
if (x->is_l()) x->right();else x->left();
break;
}
if (x->p->is_l())
if (x->is_l()) x->p->right(),x->right();
else x->left(),x->right();
else
if (x->is_l()) x->right(),x->left();
else x->p->left(),x->left();
}
x->update();
if (y==nil) root=x;
}
inline Snode *pred(Snode *node)
{
splay(root,node,nil);
Snode *last=nil,*now=node->lch;
while (now!=nil) last=now,now=now->rch;
return last;
}
inline Snode *succ(Snode *node)
{
splay(root,node,nil);
Snode *last=nil,*now=node->rch;
while (now!=nil) last=now,now=now->lch;
return last;
}
inline void insert(Snode *node,int k)
{
Snode *t1=root->rank(k-1),*t2=root->rank(k);
splay(root,t2,nil);splay(root,t1,root);
root->lch->set_r(node);root->lch->update();root->update();
}
inline void remove(Snode *&node)
{
Snode *t1=pred(node),*t2=succ(node);
splay(root,t2,nil);splay(root,t1,root);
root->lch->set_r(nil);root->lch->update();root->update();
node=nil;
}
inline int order(Snode *node)
{
splay(root,node,nil);return root->lch->size+1;
}
int main()
{
nil->id=-1;
newnode(ld,0);newnode(rd,0);
root=rd;rd->set_l(ld);ld->update();rd->update();
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i)
{
scanf("%d",&x);Snode *tmp=pred(rd);
splay(root,rd,nil);splay(root,tmp,root);
newnode(pos[x],x);root->lch->set_r(pos[x]);
root->lch->update();root->update();
splay(root,pos[x],nil);
}
for (int i=1;i<=m;++i)
{
do opt=getchar();while (opt=='\n' || opt==' ');
do ch=getchar();while (ch!=' ');
if (opt=='T') scanf("%d",&x),remove(pos[x]),newnode(pos[x],x),insert(pos[x],2);
if (opt=='B') scanf("%d",&x),remove(pos[x]),newnode(pos[x],x),insert(pos[x],n+1);
if (opt=='I') scanf("%d%d",&x,&y),z=order(pos[x]),remove(pos[x]),newnode(pos[x],x),insert(pos[x],z+y);
if (opt=='A') scanf("%d",&x),printf("%d\n",order(pos[x])-2);
if (opt=='Q') scanf("%d",&x),printf("%d\n",root->rank(x+1)->id);
}
}

BZOJ-1861 Book 书架 Splay的更多相关文章

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

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

  2. [bzoj 1861][zjoi2006] 书架

    传送门 Description 1. Top S--表示把编号为S的书放在最上面. 2. Bottom S--表示把编号为S的书放在最下面. 3. Insert S T--T∈{-1,0,1},若编号 ...

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

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

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

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

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

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

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

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

  7. BZOJ 1861: [Zjoi2006]Book 书架

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

  8. BZOJ 1861 书架

    (╯-_-)╯╧╧ 此处为错误代码. #include<iostream> #include<cstdio> #include<cstring> #include& ...

  9. bzoj 1861 splay

    就是裸地splay,然后自己写的不是特别好,tle了,最近时间比较紧迫,有时间了改下,在此记录 另附转载pascal AC代码最下面 /******************************** ...

  10. BZOJ 1861书架

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

随机推荐

  1. AC日记——神奇的幻方 洛谷 P2615(大模拟)

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

  2. xampp 用phpmyadmin在页面上修改密码后,无法登陆,密码没问题

    xampp 用phpmyadmin在页面上修改密码后,无法登陆,密码没问题一直提示密码错误, 什么原因? ------解决方案--------------------改了密码之后,phpmyadmin ...

  3. mongoVUE1.5.3 破解方法

    MongoVUE是个免费软件,但超过15天后功能受限.可以通过删除以下注册表项来解除限制: [HKEY_CURRENT_USER\Software\Classes\CLSID\{B1159E65-82 ...

  4. java 20 - 9 带有缓冲区的字节输出流和字节输入流

    由之前字节输入的两个方式,我们可以发现,通过定义数组读取数组的方式比一个个字节读取的方式快得多. 所以,java就专门提供了带有缓冲区的字节类: 缓冲区类(高效类) 写数据:BufferedOutpu ...

  5. 【WIN10】基本控件

    先發個下載地址: http://yunpan.cn/cHuCqYzvsWFAL  访问密码 3470 說明一下.這個示例只是最簡單的演示,並不能提供太大的實用價值. 後面會介紹 Bing & ...

  6. slatsatck file模块2种写法及系统初始化

    一 . lamp搭建   file2种写法 saltstack--一键yum lamp:---请注意重点: http://www.blogs8.cn/posts/WLjId80 知识点: 文件的2种写 ...

  7. 矩形覆盖-我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

    class Solution { public: int rectCover(int number) { ; ; ; ||number==) ; ) ; ;i<number+;i++){ res ...

  8. REST签名认证

    139 开放平台与应用之间以REST协议进行通讯,为了保证通信的安全性,开放平台加入签名认证机制.应用一旦创建,系统生成唯一并且不公开的secretkey,只有应用的拥有者和开放平台知道.因此,当应用 ...

  9. [C#]動態叫用Web Service

    http://www.dotblogs.com.tw/jimmyyu/archive/2009/04/22/8139.aspx 摘要 Web Service對大家來說想必都不陌生,也大都了解Web S ...

  10. python数字图像处理(11):图像自动阈值分割

    图像阈值分割是一种广泛应用的分割技术,利用图像中要提取的目标区域与其背景在灰度特性上的差异,把图像看作具有不同灰度级的两类区域(目标区域和背景区域)的组合,选取一个比较合理的阈值,以确定图像中每个像素 ...