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

题解:

题目要求支持在数列中移动、询问元素,平衡树毫无疑问可以解决这种问题。但是,区间线段树也可以解决这个问题。

每个线段树节点记录对应的区间里有多少本书,则询问操作变成了单点访问、区间求和。

因为该题的操作只有交换相邻、把某个元素放到最前、把某个元素放到最后三种,所有书所占用的区间左右段点最多向外移动m,可以开n+2*m的区间来解决。

注意记录每本书在哪个位置、某个位置有什么书,移动时记得更新。

代码:

  1. var
  2. i,j,k,l,y,n,m,ls,rs,cnt:longint;
  3. t:array[..,-..]of longint;
  4. wz,bh:array[..]of longint;
  5. ch,ch2:char;
  6. procedure build(l,r,fa:longint);
  7. var x:longint;
  8. begin
  9. inc(cnt); x:=cnt; t[x,]:=l; t[x,]:=r;
  10. if t[x,]=t[fa,] then t[fa,-]:=x else t[fa,-]:=x;
  11. if l=r then
  12. begin
  13. if bh[l]> then t[x,]:=;
  14. exit;
  15. end;
  16. build(l,(l+r)div ,x); build((l+r)div +,r,x);
  17. t[x,]:=t[t[x,-],]+t[t[x,-],];
  18. end;
  19. procedure work(x,y,z:longint);
  20. begin
  21. t[x,]:=t[x,]+z;
  22. if t[x,]=t[x,] then exit;
  23. if y<=(t[x,]+t[x,])div then work(t[x,-],y,z)
  24. else work(t[x,-],y,z);
  25. end;
  26. function qq(x,l,r:longint):longint;
  27. var ll,rr:longint;
  28. begin
  29. if(t[x,]=l)and(t[x,]=r)then exit(t[x,]);
  30. ll:=t[x,]; rr:=t[x,];
  31. if r<=(ll+rr)div then exit(qq(t[x,-],l,r))
  32. else if l>(ll+rr)div then exit(qq(t[x,-],l,r))else
  33. exit(qq(t[x,-],l,(ll+rr)div )+qq(t[x,-],(ll+rr)div +,r));
  34. end;
  35. function qq2(y:longint):longint;
  36. var k,l:longint;
  37. begin
  38. k:=;
  39. while t[k,]<>t[k,] do
  40. begin
  41. l:=t[k,-];
  42. if t[l,]>=y then k:=l
  43. else begin y:=y-t[l,]; k:=t[k,-]; end;
  44. end;
  45. exit(bh[t[k,]]);
  46. end;
  47. begin
  48. readln(n,m);
  49. for i:= to n do
  50. begin
  51. read(j);
  52. bh[i+]:=j;
  53. wz[j]:=i+;
  54. end;
  55. readln;
  56. ls:=; rs:=+n+;
  57. build(,+n+,);
  58. for i:= to m do
  59. begin
  60. read(ch);
  61. read(ch2);
  62. while ch2<>' ' do read(ch2);
  63. if ch='Q' then
  64. begin
  65. readln(j); writeln(qq2(j));
  66. end else
  67. if ch='T' then
  68. begin
  69. readln(j);
  70. work(,wz[j],-);
  71. work(,ls,); bh[wz[j]]:=; wz[j]:=ls; bh[ls]:=j; dec(ls);
  72. end else
  73. if ch='B' then
  74. begin
  75. readln(j);
  76. work(,wz[j],-);
  77. work(,rs,); bh[wz[j]]:=; wz[j]:=rs; bh[rs]:=j; inc(rs);
  78. end else
  79. if ch='A' then
  80. begin
  81. readln(j);
  82. writeln(qq(,,wz[j]-));
  83. end else
  84. begin
  85. readln(j,k);
  86. if k= then continue;
  87. l:=qq(,,wz[j]);
  88. l:=qq2(l+k);
  89. y:=wz[j]; wz[j]:=wz[l]; wz[l]:=y;
  90. y:=bh[wz[j]]; bh[wz[j]]:=bh[wz[l]]; bh[wz[l]]:=y;
  91. end;
  92. end;
  93. end.

BZOJ1861[ZJOI2006]Book书架的更多相关文章

  1. [BZOJ1861][Zjoi2006]Book 书架

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

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

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

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

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

  4. 【平衡树】【pb_ds】 bzoj1861 [Zjoi2006]Book 书架

    需要用数组记录编号为i的书的位置,和位置i处的书的编号. Code: #include<cstdio> #include<ext/pb_ds/assoc_container.hpp& ...

  5. 【权值分块】bzoj1861 [Zjoi2006]Book 书架

    权值分块……rank3……没什么好说的. #include<cstdio> #include<cmath> #include<algorithm> using na ...

  6. bzoj1861 [Zjoi2006]Book 书架 splay

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

  7. 并不对劲的bzoj1861: [Zjoi2006]Book 书架

    传送门-> 这题的正确做法是splay维护这摞书. 但是并不对劲的人选择了暴力(皮这一下很开心). #include<algorithm> #include<cmath> ...

  8. bzoj1861 [Zjoi2006]Book 书架——splay

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1861 发现自己想splay的时候总是纠结那个点权是什么,因为splay原本是二分查找树... ...

  9. BZOJ 1861: [Zjoi2006]Book 书架

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

随机推荐

  1. javascript进击(六)Jquery

    引用 jQuery 如需测试 JavaScript 库,您需要在网页中引用它. 为了引用某个库,请使用 <script> 标签,其 src 属性设置为库的 URL: <!DOCTYP ...

  2. css字体转换程序(Node.js)

    我下载的是ttf文件,css导入的文件有多种格式:eot,woff,svg 在windows下,需要寻找相应的exe文件来处理或者node.js来处理: ttf2eot: https://github ...

  3. 请编程实现:产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复(百度了一下,get一种高性能算法,非递归)

    网上找到一种更好的实现方式: (1)把N个数放到容器A(int数组)中. (2)从N个数中随机取出1个数放入容器B(int数组)中. (3)把容器A中最后一个数与随机抽取的数对调 或者 把容器A中最后 ...

  4. magento 操作数据库

    查:     $read = Mage::getSingleton(“core/resource”)->getConnection(‘core_read’);     $sql = “selec ...

  5. ionic 安装教程

    2015-10-08:国庆回来发现有新版本了,特意更新结果命令失效了,然后重新装吧,结果也失败多次 大概6-7次左右,然后系统是win10,可以启用管理员命令窗口进行安装,第二次成功了!   1.准备 ...

  6. 学习笔记_过滤器详细_2(过滤器JavaWeb三大组件之一)

    过滤器详细 5 四种拦截方式 我们来做个测试,写一个过滤器,指定过滤的资源为b.jsp,然后我们在浏览器中直接访问b.jsp,你会发现过滤器执行了! 但是,当我们在a.jsp中request.getR ...

  7. Ios 给imageview 添加手势没有反应

    道理差不多,简单写写,就是给UIImage所在的UIImageView添加个单击的手势,让用户点击图片时有响应的响应. 有人用个透明的UIButton,感觉有时候不方便.   - (void)view ...

  8. iOS 获取当前媒体音量

    #import <AVFoundation/AVAudioSession.h> AVAudioSession *audioSession = [AVAudioSession sharedI ...

  9. IOS高级开发 runtime(一)

    一. 简介 IOS 开发中灵活使用runtime 会提高我们的程序性能和开发速度.要想使用runtime,首先要引入系统的头文件. <span style="font-size:18p ...

  10. Codevs 2370 小机房的树

    2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为 ...