Book 书架 bzoj-1861 Zjoi-2006

题目大意:给你一个序列,支持:将指定编号的元素抽出,放到序列顶(底);将指定编号元素左右篡位;查询指定编号元素位置;查询指定数量位置元素编号。

注释:$1\le n,m\le 8\cdot 10^4$

想法:非旋转Treap裸题

需要注意的就是那个反复横跳的操作,只需要把指定元素和它接下来要交换的元素都split出来,然后一一合并即可。

最后,附上丑陋的代码... ...

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #define N 80010
  6. #define mp make_pair
  7. using namespace std;
  8. typedef pair<int,int> par;
  9. int n,m,root;
  10. int ls[N],rs[N],size[N],key[N],fa[N];
  11. inline void pushup(int x)
  12. {
  13. size[x]=size[ls[x]]+size[rs[x]]+1;
  14. }
  15. int merge(int x,int y)
  16. {
  17. if(!x||!y) return x|y;
  18. if(key[x]>key[y])
  19. {
  20. rs[x]=merge(rs[x],y);fa[rs[x]]=x;
  21. pushup(x); return x;
  22. }
  23. ls[y]=merge(x,ls[y]);fa[ls[y]]=y;
  24. pushup(y); return y;
  25. }
  26. par split(int x,int k)
  27. {
  28. if(!k) return mp(0,x);
  29. int lson=ls[x],rson=rs[x];
  30. if(k==size[lson])
  31. {
  32. ls[x]=0;pushup(x);
  33. fa[lson]=0;
  34. return mp(lson,x);
  35. }
  36. if(k==size[lson]+1)
  37. {
  38. rs[x]=0;pushup(x);
  39. fa[rson]=0;
  40. return mp(x,rson);
  41. }
  42. if(k<size[lson])
  43. {
  44. par t=split(lson,k);
  45. ls[x]=t.second;fa[ls[x]]=x;pushup(x);
  46. return mp(t.first,x);
  47. }
  48. par t=split(rson,k-size[ls[x]]-1);
  49. rs[x]=t.first;fa[rs[x]]=x;pushup(x);
  50. return mp(x,t.second);
  51. }
  52. int getid(int x)
  53. {
  54. int flag=1,t=x,ans=0;
  55. while(t)
  56. {
  57. if(flag)ans+=size[ls[t]]+1;
  58. flag=(t==rs[fa[t]]);
  59. t=fa[t];
  60. }
  61. return ans-1;
  62. }
  63. int find(int x)
  64. {
  65. x--;int t=root;
  66. while(1)
  67. {
  68. if(x==size[ls[t]]) return t;
  69. if(x<size[ls[t]]) t=ls[t];
  70. else x-=size[ls[t]]+1,t=rs[t];
  71. }
  72. }
  73. int main()
  74. {
  75. cin >> n >> m ;
  76. for(int x,i=1;i<=n;i++)
  77. {
  78. scanf("%d",&x);
  79. size[x]=1,key[x]=rand()*rand();
  80. root=merge(root,x);
  81. }
  82. char flag[10];
  83. for(int x,y,i=1;i<=m;i++)
  84. {
  85. scanf("%s",flag);
  86. if(flag[0]=='T')
  87. {
  88. scanf("%d",&x);
  89. int id=getid(x);
  90. par t2=split(root,id+1),t1=split(t2.first,id);
  91. root=merge(t1.second,merge(t1.first,t2.second));
  92. }
  93. else if(flag[0]=='B')
  94. {
  95. scanf("%d",&x);
  96. int id=getid(x);
  97. par t2=split(root,id+1),t1=split(t2.first,id);
  98. root=merge(merge(t1.first,t2.second),t1.second);
  99. }
  100. else if(flag[0]=='I')
  101. {
  102. scanf("%d%d",&x,&y);
  103. if(!y)continue;
  104. if(y==-1)
  105. {
  106. int id=getid(x);
  107. par t3=split(root,id+1),t2=split(t3.first,id),t1=split(t2.first,id-1);
  108. root=merge(merge(merge(t1.first,t2.second),t1.second),t3.second);
  109. }
  110. else
  111. {
  112. int id=getid(x);
  113. par t3=split(root,id+2),t2=split(t3.first,id+1),t1=split(t2.first,id);
  114. root=merge(merge(merge(t1.first,t2.second),t1.second),t3.second);
  115. }
  116. }
  117. else if(flag[0]=='A')
  118. {
  119. scanf("%d",&x);
  120. printf("%d\n",getid(x));
  121. }
  122. else
  123. {
  124. scanf("%d",&x);
  125. printf("%d\n",find(x));
  126. }
  127. }
  128. return 0;
  129. }

小结:非旋转Treap就是比splay优(傲娇脸)

[bzoj1861][Zjoi2006]Book 书架_非旋转Treap的更多相关文章

  1. [bzoj3173]最长上升子序列_非旋转Treap

    最长上升子序列 bzoj-3173 题目大意:有1-n,n个数,第i次操作是将i加入到原有序列中制定的位置,后查询当前序列中最长上升子序列长度. 注释:1<=n<=10,000,开始序列为 ...

  2. [bzoj1500][NOI2005]维修数列_非旋转Treap

    维修数列 bzoj-1500 NOI-2005 题目大意:给定n个数,m个操作,支持:在指定位置插入一段数:删除一个数:区间修改:区间翻转.查询:区间和:全局最大子序列. 注释:$1\le n_{ma ...

  3. [bzoj4864][BeiJing2017Wc]神秘物质_非旋转Treap

    神秘物质 bzoj-4864 BeiJing-2017-Wc 题目大意:给定一个长度为n的序列,支持插入,将相邻两个元素合并并在该位置生成一个指定权值的元素:查询:区间内的任意一段子区间的最大值减最小 ...

  4. [bzoj1552\bzoj2506][Cqoi2014]robotic sort 排序机械臂_非旋转Treap

    robotic sort 排序机械臂 bzoj-1552 bzoj-2506 Cqoi-2014 题目大意:给定一个序列,让你从1到n,每次将[1,p[i]]这段区间反转,p[i]表示整个物品权值第i ...

  5. [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树

    二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...

  6. BZOJ1500[NOI2005]维修数列——非旋转treap

    题目描述 请写一个程序,要求维护一个数列,支持以下 6 种操作: 请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格 输入 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初 ...

  7. 非旋转Treap:用运行时间换调试时间的有效手段

    非旋转Treap:用运行时间换调试时间的有效手段   Hello大家好,我们今天来聊一聊非旋转Treap. 相信各位或多或少都做过些序列上的问题.如果水题我们考虑暴力:不强制在线我们可能用过莫队和待修 ...

  8. [BZOJ1861][Zjoi2006]Book 书架

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

  9. 关于非旋转treap的学习

    非旋转treap的操作基于split和merge操作,其余操作和普通平衡树一样,复杂度保证方式与旋转treap差不多,都是基于一个随机的参数,这样构出的树树高为\(logn\) split 作用:将原 ...

随机推荐

  1. class--类②

    定义 C++ 对象 类提供了对象的蓝图,所以基本上,对象是根据类来创建的.声明类的对象,就像声明基本类型的变量一样.下面的语句声明了类 Box 的两个对象: Box Box1; // 声明 Box1, ...

  2. 洛谷P3809 后缀数组模板

    题目:https://www.luogu.org/problemnew/show/P3809 刚学了后缀数组,看人家手写演示了半天,大概明白了过程,但完全写不出来代码: 于是借鉴了许多,不过都差不多, ...

  3. 协议-网络-安全协议:SSH(安全外壳协议)

    ylbtech-协议-网络-安全协议:SSH(安全外壳协议) SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定:SSH 为建立 ...

  4. k-means 聚类前的数据分析

    原始数据 Say you are given a data set where each observed example has a set of features, but has nolabel ...

  5. [Apple开发者帐户帮助]三、创建证书(1)证书概述

    在开发应用程序的过程中,您将创建不同的证书类型,以便在不同的上下文中使用.您将为iOS,tvOS和watchOS应用程序使用相同的证书集,并为macOS应用程序使用不同的证书集.您将使用开发证书在设备 ...

  6. MySQL实现递归查询

    DROP FUNCTION IF EXISTS queryChildrenCaseInfo;CREATE FUNCTION queryChildrenCaseInfo(cId INT)RETURNS ...

  7. Django模板常用语法规则

    Django 模板标签 if/else 标签 for 标签 ifequal/ifnotequal 标签 注释标签 过滤器 include 标签 URL标签 模板继承   if/else 标签 1. 基 ...

  8. bcg库使用心得两则

    作者:朱金灿 来源:http://blog.csdn.net/clever101 最近帮同事解决了两个BCG库的使用问题,特记录下来. 一是在outlook风格停靠栏上创建对话框的做法.代码如下: C ...

  9. 2、scala条件控制与循环

    1.  if表达式 2.  句终结符.块表达式 3.  输入与输出 4.  循环 5.  高级for循环 1.  if表达式 if表达式的定义:scala中,表达式是有值的,就是if或者else中最后 ...

  10. Typeclassopedia

    https://wiki.haskell.org/wikiupload/8/85/TMR-Issue13.pdf By Brent Yorgey, byorgey@gmail.com Original ...