博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[ZJOI2006]书架
阅读量:7098 次
发布时间:2019-06-28

本文共 4277 字,大约阅读时间需要 14 分钟。

Time Limit: 4 Sec  Memory Limit: 64 MB

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

题解:

我们将所有的书按照在书架中的位置建一棵splay,然后对于题目中的操作。

1.top

找到当前点并旋转到根,将它的左子树链接到它的后继的左子树。

2.bottom

找到当前点并旋转到根,将它的右子树链接到它的前驱的右子树。

 

3.insert

找到它的前驱或者后继,然后swap一下里面的信息。

4.ask

找到这个店,然后旋转到根,输出左节点的size。

5.query

直接在树上查找就好。

细节的话,前两个操作注意判断一下左子树或右子树是否为空。

1 //Never forget why you start  2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #define ll(x) bst[x].child[0] 9 #define rr(x) bst[x].child[1] 10 #define son(x,t) bst[x].child[t] 11 using namespace std; 12 int n,m; 13 int root,cnt; 14 struct node{ 15 int fa,child[2],x,size; 16 }bst[100005]; 17 void push_up(int r){ 18 bst[r].size=bst[ll(r)].size+bst[rr(r)].size+1; 19 } 20 void rotate(int r,int t){ 21 int fa=bst[r].fa; 22 son(fa,!t)=son(r,t);bst[son(r,t)].fa=fa; 23 son(bst[fa].fa,son(bst[fa].fa,1)==fa)=r;bst[r].fa=bst[fa].fa; 24 son(r,t)=fa;bst[fa].fa=r; 25 push_up(fa); 26 push_up(r); 27 } 28 void splay(int r,int goal){ 29 int fa=bst[r].fa; 30 while(fa!=goal){ 31 if(bst[fa].fa==goal)rotate(r,son(fa,0)==r); 32 else{ 33 int t=son(bst[fa].fa,0)==fa; 34 if(r==son(fa,t))rotate(r,!t),rotate(r,t); 35 else rotate(fa,t),rotate(r,t); 36 } 37 fa=bst[r].fa; 38 } 39 if(goal==0)root=r; 40 } 41 int pos[100005]; 42 void insert(int x){ 43 cnt++;pos[x]=cnt; 44 son(cnt,0)=son(cnt,1)=bst[cnt].fa=0; 45 bst[cnt].x=x; 46 bst[cnt].size=1; 47 if(cnt>1){ 48 bst[cnt].fa=cnt-1; 49 son(cnt-1,1)=cnt; 50 splay(cnt,0); 51 } 52 } 53 int find(int root,int k){ 54 int y=bst[son(root,0)].size; 55 if(y+1==k)return root; 56 else if(y>=k)return find(son(root,0),k); 57 else return find(son(root,1),k-y-1); 58 } 59 void top(int x){ 60 x=pos[x]; 61 splay(x,0); 62 if(bst[son(x,0)].size==0)return; 63 if(bst[son(x,1)].size==0){son(x,1)=son(x,0);son(x,0)=0;bst[son(x,1)].fa=x;return;} 64 else{ 65 int y=find(root,bst[son(x,0)].size+2); 66 son(y,0)=son(x,0); 67 bst[son(x,0)].fa=y; 68 son(x,0)=0; 69 splay(y,0); 70 } 71 } 72 void bottom(int x){ 73 x=pos[x]; 74 splay(x,0); 75 if(bst[son(x,1)].size==0)return; 76 if(bst[son(x,0)].size==0){son(x,0)=son(x,1);son(x,1)=0;bst[son(x,0)].fa=x;return;} 77 else{ 78 int y=find(root,bst[son(x,0)].size); 79 son(y,1)=son(x,1); 80 bst[son(x,1)].fa=y; 81 son(x,1)=0; 82 splay(y,0); 83 } 84 } 85 void ins(int x,int t){ 86 int a=x,b; 87 if(!t)return; 88 x=pos[x]; 89 splay(x,0); 90 if(t==1){ 91 if(son(x,1)==0)return; 92 int y=find(root,bst[son(x,0)].size+2); 93 b=bst[y].x; 94 swap(bst[x].x,bst[y].x); 95 swap(pos[a],pos[b]); 96 splay(y,0); 97 } 98 else{ 99 if(son(x,0)==0)return;100 int y=find(root,bst[son(x,0)].size);101 b=bst[y].x;102 swap(bst[x].x,bst[y].x);103 swap(pos[a],pos[b]);104 splay(y,0);105 }106 }107 int ask(int x){108 x=pos[x];109 splay(x,0);110 return bst[son(x,0)].size;111 }112 int query(int x){113 return bst[find(root,x)].x;114 }115 int main(){116 int i,j;117 root=0;118 scanf("%d%d",&n,&m);119 for(i=1;i<=n;i++){120 scanf("%d",&j);121 insert(j);122 }123 for(i=1;i<=m;i++){124 char s[10];125 int x;126 scanf("%s%d",s,&x);127 if(s[0]=='T')top(x);128 if(s[0]=='B')bottom(x);129 if(s[0]=='I'){130 int k;131 scanf("%d",&k);132 ins(x,k);133 }134 if(s[0]=='A')printf("%d\n",ask(x));135 if(s[0]=='Q')printf("%d\n",query(x));136 }137 return 0;138 }

 

转载于:https://www.cnblogs.com/huangdalaofighting/p/8256764.html

你可能感兴趣的文章
不仅仅是远程桌面,微软“桌面云”技术概览 (1)远程桌面协议 RDP 8.0
查看>>
校园网应用分析
查看>>
Python的面向对象、Class 概念与使用
查看>>
从传统运维到云运维演进历程之软件定义存储(三)下
查看>>
技术分享连载(二十)
查看>>
Java -- JDBC 学习--调用函数&存储过程
查看>>
关于PC或笔记本的一些安全设定
查看>>
DNS Security Tips
查看>>
吴家坟女子专修学院郭杜校区计算机分院的学年总结
查看>>
OpenCV实现手写体数字训练与识别
查看>>
Linux IP、DNS、Route配置
查看>>
Windows Server 2012 R2 NIC Teaming
查看>>
文件系统一些概念【更新完毕】
查看>>
Eclipse的一个重要功能
查看>>
HCE Benchmark
查看>>
设置基于Windows策略的QOS
查看>>
配置Linux日志文件
查看>>
黑客攻防专题三:名词介绍
查看>>
吐槽一下现在的代码编辑器
查看>>
笔记—TCP有限状态机分析
查看>>