题目描述

输入

输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。

输出

输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,Pi表示第i次操作前第i小的物品所在的位置。 注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。

样例输入

6
3 4 5 1 6 2

样例输出

4 6 4 5 6 6


题解

splay

先将原数据从小到大排序,类似于离散化,把它们的排名存入splay中。

那么第k小的数的数组下标就是k。

区间反转即可。

  1. #include <cstdio>
  2. #include <algorithm>
  3. #define N 100005
  4. using namespace std;
  5. struct data
  6. {
  7. int num , pos;
  8. }a[N];
  9. int c[2][N] , fa[N] , tag[N] , si[N] , id[N] , root;
  10. bool cmp(data a , data b)
  11. {
  12. return a.num == b.num ? a.pos < b.pos : a.num < b.num;
  13. }
  14. void pushup(int k)
  15. {
  16. si[k] = si[c[0][k]] + si[c[1][k]] + 1;
  17. }
  18. void pushdown(int k)
  19. {
  20. if(tag[k])
  21. {
  22. swap(c[0][c[0][k]] , c[1][c[0][k]]);
  23. swap(c[0][c[1][k]] , c[1][c[1][k]]);
  24. tag[c[0][k]] ^= 1;
  25. tag[c[1][k]] ^= 1;
  26. tag[k] = 0;
  27. }
  28. }
  29. void build(int l , int r , int f)
  30. {
  31. if(l > r) return;
  32. int mid = (l + r) >> 1;
  33. build(l , mid - 1 , mid);
  34. build(mid + 1 , r , mid);
  35. fa[id[mid]] = id[f];
  36. c[mid > f][id[f]] = id[mid];
  37. pushup(id[mid]);
  38. }
  39. void rotate(int &k , int x)
  40. {
  41. int y = fa[x] , z = fa[y] , l , r;
  42. l = (c[0][y] != x);
  43. r = l ^ 1;
  44. if(y == k) k = x;
  45. else if(c[0][z] == y) c[0][z] = x;
  46. else c[1][z] = x;
  47. fa[x] = z;
  48. fa[y] = x;
  49. fa[c[r][x]] = y;
  50. c[l][y] = c[r][x];
  51. c[r][x] = y;
  52. pushup(y);
  53. pushup(x);
  54. }
  55. void splay(int &k , int x)
  56. {
  57. while(x != k)
  58. {
  59. int y = fa[x] , z = fa[y];
  60. if(y != k)
  61. {
  62. if(c[0][y] == x ^ c[0][z] == y) rotate(k , x);
  63. else rotate(k , y);
  64. }
  65. rotate(k , x);
  66. }
  67. }
  68. int getrank(int x)
  69. {
  70. if(x == root) return si[c[0][x]] + 1;
  71. int r = getrank(fa[x]);
  72. pushdown(x);
  73. if(x == c[0][fa[x]]) r -= si[c[1][x]] + 1;
  74. else r += si[c[0][x]] + 1;
  75. return r;
  76. }
  77. int find(int k , int x)
  78. {
  79. pushdown(k);
  80. if(x <= si[c[0][k]]) return find(c[0][k] , x);
  81. else if(x > si[c[0][k]] + 1) return find(c[1][k] , x - si[c[0][k]] - 1);
  82. else return k;
  83. }
  84. int main()
  85. {
  86. int n , i;
  87. scanf("%d" , &n);
  88. for(i = 1 ; i <= n ; i ++ )
  89. {
  90. scanf("%d" , &a[i].num);
  91. a[i].pos = i;
  92. }
  93. sort(a + 1 , a + n + 1 , cmp);
  94. for(i = 1 ; i <= n ; i ++ )
  95. id[a[i].pos + 1] = i;
  96. id[1] = n + 1;
  97. id[n + 2] = n + 2;
  98. build(1 , n + 2 , 0);
  99. root = id[(n + 3) >> 1];
  100. for(i = 1 ; i <= n ; i ++ )
  101. {
  102. int ri = getrank(i) , tx , ty;
  103. printf("%d%c" , ri - 1 , i == n ? '\n' : ' ');
  104. tx = find(root , i);
  105. ty = find(root , ri + 1);
  106. splay(root , tx);
  107. splay(c[1][root] , ty);
  108. swap(c[0][c[0][c[1][root]]] , c[1][c[0][c[1][root]]]);
  109. tag[c[0][c[1][root]]] ^= 1;
  110. }
  111. return 0;
  112. }

【bzoj1552】[Cerc2007]robotic sort的更多相关文章

  1. 【BZOJ1552】[Cerc2007]robotic sort Splay

    [BZOJ1552][Cerc2007]robotic sort Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N ...

  2. 【bzoj1552/3506】[Cerc2007]robotic sort splay翻转,区间最值

    [bzoj1552/3506][Cerc2007]robotic sort Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000. ...

  3. 洛谷 P4402 BZOJ1552 / 3506 [Cerc2007]robotic sort 机械排序

    FHQ_Treap 太神辣 蒟蒻初学FHQ_Treap,于是来到了这道略显板子的题目 因为Treap既满足BST的性质,又满足Heap的性质,所以,对于这道题目,我们可以将以往随机出的额外权值转化为每 ...

  4. 【HDOJ】1890 Robotic Sort

    伸展树伤不起啊,很容易wa,很容易T,很容易M. /* 1890 */ #include <iostream> #include <string> #include <m ...

  5. BZOJ1552/3506 [Cerc2007]robotic sort

    Splay 与之前不同的是如果你仅仅是翻转左右区间的话可以在find里面做因为对他有影响的子树在做之前一定在他的上面从上到下搜索的过程可以把rever做了. 但这道题要求我们输出转换之前的,因此不能保 ...

  6. [BZOJ1552][Cerc2007]robotic sort

    [BZOJ1552][Cerc2007]robotic sort 试题描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N个用空格隔开的正整数 ...

  7. BZOJ 1552: [Cerc2007]robotic sort( splay )

    kpm大神说可以用块状链表写...但是我不会...写了个splay.... 先离散化 , 然后splay结点加个min维护最小值 , 就可以了... ( ps BZOJ 3506 题意一样 , 双倍经 ...

  8. bzoj 1552: [Cerc2007]robotic sort

    1552: [Cerc2007]robotic sort Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1198  Solved: 457[Submit] ...

  9. 【LeetCode】147. Insertion Sort List 解题报告(Python)

    [LeetCode]147. Insertion Sort List 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: h ...

随机推荐

  1. 字符函数库 cctype

    <cctype> (ctype.h) Character handling functions This header declares a set of functions to cla ...

  2. iOS label换行 自适应

    //自动折行设置 addressDetailLab.lineBreakMode = NSLineBreakByWordWrapping; addressDetailLab.numberOfLines ...

  3. Android中如何将Bitmap byte裸数据转换成Bitmap图片int数据

    Android中如何将Bitmap byte裸数据转换成Bitmap图片int数据 2014-06-11 10:45:14   阅读375次 我们在JNI中处理得到的BMP图片Raw数据,我们应该如何 ...

  4. C#,js数据排序及其操作

    List<int> listint=new List<int>{2,1,7,3,8,5,4,6};listint.Sort((x, y) => x - y); var a ...

  5. GenericApp SampleApp SimpleAp的区别

    SampleApp3.2 Zigbee2007 协议栈实验例程表演说明C:\Texas Instruments\ZStack-2.0.0-1.2.0\Projects\zstack\Samples\S ...

  6. UVA - 11400 Lighting System Design (区间DP)

    这个问题有两个点需要注意: 1. 对于一种灯泡,要么全换,要么全不换. 证明: 设一种灯泡单价为p1,电池价格为k1,共需要L个,若把L1个灯泡换成单价为p2,电池为k2的灯泡,产生的总花费为p1*L ...

  7. Node.js学习 - Global Object

    全局对象:特殊的对象,它及其所有属性都可以在程序的任何地方访问. __filename 表示当前正在执行的脚本的文件名.它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同. 如果在 ...

  8. Spring的事务传播机制

    1.事务传播类型     新建事务 required required_new   - 挂起当前    非事务方式运行 supports not_supported  - 挂起当前 never    ...

  9. editplus 正则删换行

    editplus regular expression  ctrl+h 1.替换开始是空行 ^[\t ]*\n 2.替换换行 \n 3.替换包含某字符 .*@126.* excel去重复(或者保留一个 ...

  10. 极光推送,极光IM使用指南(AndroidStudio)

    到官网创建一个应用,然后下载上面的例子程序,对照集成文档,把libs里的jar和so文件放入到本项目的libs下面,记得把jar要as a library,然后配置清单文件,对照着Demo来,配置好之 ...