题目描述

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.把第一个数放在顶端也没特判
代码如下:
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. #include<cstdlib>
  7. #include<ctime>
  8. using namespace std;
  9. const int N=,INF=;
  10. struct node
  11. {
  12. int x,size,book;
  13. node *child[],*fa;
  14. }a[N*];
  15. node *pos=a,*root,*id[N];
  16. void newnode(node *&r,int key,node *ff,int number)
  17. {
  18. r=pos++;
  19. r->size=,id[number]=r;
  20. r->x=key;r->fa=ff;r->book=number;
  21. r->child[]=r->child[]=NULL;
  22. }
  23. int gi()
  24. {
  25. int str=;char ch=getchar();
  26. while(ch>'' || ch<'')ch=getchar();
  27. while(ch>=''&& ch<='')str=str*+ch-'',ch=getchar();
  28. return str;
  29. }
  30. int n,m;
  31. void updata(node *&r)
  32. {
  33. if(r){
  34. r->size=(r->child[]?r->child[]->size:)+(r->child[]?r->child[]->size:)+;
  35. return ;
  36. }
  37. }
  38. void rotate(node *&r,bool t)
  39. {
  40. node *y=r->fa;
  41. y->child[!t]=r->child[t];
  42. if(r->child[t])r->child[t]->fa=y;
  43. r->fa=y->fa;
  44. if(y->fa)y->fa->child[y->fa->child[]==y]=r;
  45. r->child[t]=y;
  46. y->fa=r;
  47. updata(y);
  48. updata(r);
  49. updata(r->fa);
  50. }
  51. void splay(node *r,node *g)
  52. {
  53. while(r->fa!=g)
  54. {
  55. if(r->fa->fa==g)rotate(r,r->fa->child[]==r);
  56. else{
  57. node *y=r->fa;
  58. bool t=y->fa->child[]==y;
  59. if(y->child[t]==r)rotate(r,!t);
  60. else rotate(y,t);
  61. rotate(r,t);
  62. }
  63. }
  64. if(g==NULL)root=r;
  65. }
  66. void insert(node *&r,int key,node *fa,int number)
  67. {
  68. if(r==NULL){
  69. newnode(r,key,fa,number);
  70. splay(r,NULL);
  71. return;
  72. }
  73. else insert(r->child[key>r->x],key,r,number);
  74. }
  75. node *pre,*nxt;
  76. char s[];
  77. void getpre(node *r,int key)
  78. {
  79. if(!r)return ;
  80. if(r->x>=key)getpre(r->child[],key);
  81. else pre=r,getpre(r->child[],key);
  82. }
  83. void getnext(node *r,int key)
  84. {
  85. if(!r)return ;
  86. if(r->x<=key)getnext(r->child[],key);
  87. else nxt=r,getnext(r->child[],key);
  88. }
  89. void Ask(int x)
  90. {
  91. splay(id[x],NULL);
  92. printf("%d\n",root->child[]?root->child[]->size:);
  93. return ;
  94. }
  95. int getrank(node *r,int rk)
  96. {
  97. while(r){
  98. int d=r->child[]?r->child[]->size:;
  99. if(rk==d+)return r->book;
  100. if(rk<d+)r=r->child[];
  101. else rk-=d+,r=r->child[];
  102. }
  103. return -;
  104. }
  105. node *findmax(node *r)
  106. {
  107. if(r->child[])return findmax(r->child[]);
  108. else return r;
  109. }
  110. int maxn=,minn=;
  111. void Delet(int x)
  112. {
  113. node *y;
  114. splay(id[x],NULL);
  115. if(root->child[]){
  116. y=findmax(root->child[]);
  117. splay(y,root);
  118. y->child[]=root->child[];
  119. y->fa=NULL;
  120. if(root->child[])
  121. root->child[]->fa=y;
  122. root=y;
  123. updata(y);
  124. }
  125. else{
  126. root=root->child[];
  127. root->fa=NULL;
  128. }
  129. }
  130. void Totop(int x,bool t)
  131. {
  132. Delet(x);
  133. if(!t)
  134. insert(root,--minn,NULL,x);
  135. else
  136. insert(root,++maxn,NULL,x);
  137. }
  138. void change(int x,int y)
  139. {
  140. node *kl;
  141. if(y==)getnext(root,id[x]->x),kl=nxt;
  142. else getpre(root,id[x]->x),kl=pre;
  143. y=kl->book;
  144. swap(id[x],id[y]);
  145. swap(id[x]->book,id[y]->book);
  146. }
  147. int main()
  148. {
  149. int x,y;
  150. n=gi();m=gi();maxn=n;
  151. for(int i=;i<=n;i++){
  152. x=gi();
  153. insert(root,i,NULL,x);
  154. }
  155. int cc=;
  156. while(m--){
  157. scanf("%s%d",s,&x);
  158. if(s[]=='A')Ask(x);
  159. else if(s[]=='Q')printf("%d\n",getrank(root,x));
  160. else if(s[]=='I'){scanf("%d",&y);if(y)change(x,y);}
  161. else if(s[]=='T')Totop(x,);
  162. else if(s[]=='B')Totop(x,);
  163. }
  164. return ;
  165. }

[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. 关于python词典(Dictionary)的get()用法

    先贴出参考链接:http://www.runoob.com/python/att-dictionary-get.html get()方法语法: dict.get(key, default=None) ...

  2. 项目Beta冲刺Day1

    项目进展 李明皇 今天解决的进度 点击首页list相应条目将信息传到详情页 明天安排 优化信息详情页布局 林翔 今天解决的进度 前后端连接成功 明天安排 开始微信前端+数据库写入 孙敏铭 今天解决的进 ...

  3. RxSwift(一)

    文/iOS_Deve(简书作者) 原文链接:http://www.jianshu.com/p/429b5160611f 著作权归作者所有,转载请联系作者获得授权,并标注"简书作者" ...

  4. ssh框架-Struts2(二)

    上篇文章我们了解了怎么配置struts.xml文件,以及前端控制器配置怎么配置,,Action进阶,Result结果配置,Struts2中的Servlet的API的访问,以及怎么获得请求参数.今天我们 ...

  5. Codeforces 343D WaterTree - 线段树, DFS序

    Description Translated by @Nishikino_Maki from Luogu 行吧是我翻的 Mad scientist Mike has constructed a roo ...

  6. 服务器批量管理软件ansible安装以及配置

    1.yum安装(管理主机以及被管理主机都需要安装) yum install epel-release yum install ansible 2.配置管理主机 vim /etc/ansible/hos ...

  7. python——常用模块

    python--常用模块 1 什么是模块: 模块就是py文件 2 import time #导入时间模块 在Python中,通常有这三种方式来表示时间:时间戳.元组(struct_time).格式化的 ...

  8. flask开发表单

    from flask import Flask from flask import render_template from flask import request from flask impor ...

  9. PhantomJS命令行选项

    支持命令行选项有: --help或-h列出所有可能的命令行选项.立即停止,不会运行一个脚本作为参数传递. --version或-v打印的版本PhantomJS.立即停止,不会运行一个脚本作为参数传递. ...

  10. JS面向对象使用面向对象进行开发

      面向对象基础一之初体验使用面向对象进行开发 对 JS 中的面向对象的基础进行讲述, 初体验使用面向对象进行开发 主要内容是 面向对象的概念及特性 用面向对象的方式解决简单的标签创建实例 一些基础的 ...