http://www.lydsy.com/JudgeOnline/problem.php?id=1861

(题面复制于洛谷)

题目描述

小T有一个很大的书柜。这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列。她用1到n的正整数给每本书都编了号。

小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本。由于这些书太有吸引力了,所以她看完后常常会忘记原来是放在书柜的什么位置。不过小T的记忆力是非常好的,所以每次放书的时候至少能够将那本书放在拿出来时的位置附近,比如说她拿的时候这本书上面有X本书,那么放回去时这本书上面就只可能有X-1、X或X+1本书。

当然也有特殊情况,比如在看书的时候突然电话响了或者有朋友来访。这时候粗心的小T会随手把书放在书柜里所有书的最上面或者最下面,然后转身离开。

久而久之,小T的书柜里的书的顺序就会越来越乱,找到特定的编号的书就变得越来越困难。于是她想请你帮她编写一个图书管理程序,处理她看书时的一些操作,以及回答她的两个提问:(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语句你应该输出一行,一个数,代表询问的答案。

输入输出样例

输入样例#1:

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
输出样例#1:

2
9
9
7
5
3

说明

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

————————————————————————————————

首先我们splay平衡条件为当前元素插入顺序,插入顺序的关系为lson<root<rson。

然后多开一个数组pos记录序号所代表的树上的位置。

剩下的正常splay就行了。

PS1:读入字符串推荐一个一个字符读入……不然洛谷AC,BZOJ RE。

PS2:top(x)操作基本上是:

1.将xsplay。

2.找到它后面编号的点y,删掉x,将y作为新的假根节点。

3.将y作为x的右儿子(将x重新添加回来)。

显然bottom操作和他基本类似。

又显然ins也类似。

又显然其他操作很显然。

#include<cstdio>
#include<queue>
#include<cctype>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
int fa[N],tr[N][],key[N],size[N],pos[N];
int root,sz,n,m;
inline bool get(int x){
return tr[fa[x]][]==x;
}
inline void update(int x){
size[x]=;
if(x){
if(tr[x][])size[x]+=size[tr[x][]];
if(tr[x][])size[x]+=size[tr[x][]];
if(tr[x][])pos[key[tr[x][]]]=tr[x][];
if(tr[x][])pos[key[tr[x][]]]=tr[x][];
pos[key[x]]=x;
}
return;
}
inline void rotate(int x){
int old=fa[x],oldf=fa[old],which=get(x);
tr[old][which]=tr[x][which^];fa[tr[old][which]]=old;
fa[old]=x;tr[x][which^]=old;fa[x]=oldf;
if(oldf)tr[oldf][tr[oldf][]==old]=x;
update(old);update(x);
return;
}
inline void splay(int x){
int f=fa[x];
while(f){
if(fa[f])rotate((get(x)==get(f)?f:x));
rotate(x);f=fa[x];
}
root=x;
return;
}
inline void insert(int v){
sz++;tr[sz][]=tr[sz][]=fa[sz]=;
key[sz]=v;pos[v]=sz;size[sz]=;
if(sz==)root=sz;
else{
tr[sz-][]=sz;
fa[sz]=sz-;
update(fa[sz]);splay(sz);
}
return;
}
inline int find(int x,int v){
int y=tr[x][];
if(size[y]+==v)return x;
else if(size[y]>=v)return find(y,v);
else return find(tr[x][],v-size[y]-);
}
inline void top(int x){
x=pos[x];
splay(x);
if(!tr[x][])return;
if(!tr[x][])tr[x][]=tr[x][],tr[x][]=;
else{
int y=find(root,size[tr[x][]]+);//找到它后面编号的点
fa[tr[root][]]=y;
tr[y][]=tr[root][];
tr[root][]=;
splay(y);
}
return;
}
inline void bottom(int x){
x=pos[x];
splay(x);
if(!tr[x][])return;
if(!tr[x][])tr[x][]=tr[x][],tr[x][]=;
else{
int y=find(root,size[tr[x][]]);//找到它后面编号的点
fa[tr[root][]]=y;
tr[y][]=tr[root][];
tr[root][]=;
splay(y);
}
return;
}
inline void ins(int x,int t){
if(!t)return;
splay(pos[x]);
int y=find(root,t==?size[tr[pos[x]][]]+:size[tr[pos[x]][]]);
int x1=key[y],x2=pos[x];
swap(pos[x],pos[x1]);
swap(key[x2],key[y]);
return;
}
inline int ask(int x){
x=pos[x];
splay(x);
return size[tr[x][]];
}
inline int query(int x){
return key[find(root,x)];
}
inline char getc(){
char c=getchar();
while(c==' '||c=='\n')c=getchar();
char ch=c;
while(c>='a'&&c<='z')c=getchar();
return ch;
}
int main(){
n=read();
m=read();
for(int i=;i<=n;i++){
int t=read();
insert(t);
}
for(int i=;i<=m;i++){
char ch=getc();
if(ch=='T')top(read());
if(ch=='B')bottom(read());
if(ch=='I'){
int s=read();
int t=read();
ins(s,t);
}
if(ch=='A')printf("%d\n",ask(read()));
if(ch=='Q')printf("%d\n",query(read()));
}
return ;
}

BZOJ1861:[ZJOI2006]书架——题解的更多相关文章

  1. [BZOJ1861][ZJOI2006]书架

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

  2. BZOJ1861[Zjoi2006]书架——非旋转treap

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

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

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

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

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

  5. [BZOJ1861][Zjoi2006]Book 书架

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

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

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

  7. 「luogu2569」[ZJOI2006] 书架

    「luogu2569」[ZJOI2006]书架 题目大意 给定一个长度为 \(n\) 序列,序列中第 \(i\) 个元素有编号 \(a_i(a_i \in \Z \cap [1,n])\),需要支持五 ...

  8. 洛谷 P2596 [ZJOI2006]书架 解题报告

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

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

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

随机推荐

  1. 跨平台编译Go程序(交叉编译)

    作用:比如你手头只有Mac系统,而你的用户有Linux和Windows的,他们也想用,你可以通过交叉编译出Linux和Windows上的可执行文件给他们用 (1)首先进入go/src 源码所在目录,执 ...

  2. Unity Container中的几种注册方式与示例

    1.实例注册 最简单的注册方式就是实例注册,Unity 容器负责维护对一个类型的单例引用,比如: 有如下的实际类型: namespace ConsoleSample { public class Sa ...

  3. WSL跑linux服务程序

    前段时间折腾了一次WSL下的Apache,无奈遇到各种奇葩问题,总是解决不了,最终放弃,甚至得出了一个现在看来比较可笑的结论:WSL是不可能跑Linux服务程序的! 当时的思路想歪了,由于Apache ...

  4. 「日常训练」Alternative Thinking(Codeforces Round #334 Div.2 C)

    题意与分析 (CodeForces - 603A) 这题真的做的我头疼的不得了,各种构造样例去分析性质... 题意是这样的:给出01字符串.可以在这个字符串中选择一个起点和一个终点使得这个连续区间内所 ...

  5. MySQL☞关联查询

    关联查询:所需要的数据来源于多张表,通过表的连接查询(关联查询)来查询多张表中的数据 格式: select 别名1 . */列名 , 别名2 . */列名 from 表名1  别名1 , 表名2  别 ...

  6. grep命令及正则

    文本查找 grep,egrep,fgrep grep :Global Research 根据模式搜索文本,并将符合模式的文本行显示出来 模式:Pattern,文本字符和正则的元字符组合而成匹配条件 g ...

  7. TPO-10 C2 Return a literature book

    TPO-10 C2 Return a literature book 第 1 段 1.Listen to a conversation between a student and an employe ...

  8. leetcode-颜色分类

     颜色分类     给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中,我们使用整数 0. 1 和 2 分别表示 ...

  9. 【转】: 探索Lua5.2内部实现:虚拟机指令(3) Upvalues & Globals

    在编译期,如果要访问变量a时,会依照以下的顺序决定变量a的类型: a是当前函数的local变量 a是外层函数的local变量,那么a是当前函数的upvalue a是全局变量 local变量本身就存在于 ...

  10. Fluent Python: Mutable Types as Parameter Defaults: Bad Idea

    在Fluent Python一书第八章有一个示例,未看书以先很难理解这个示例运行的结果,我们先看结果,然后再分析问题原因: 定义了如下Bus类: class Bus: def __init__(sel ...