Splay

与之前不同的是如果你仅仅是翻转左右区间的话可以在find里面做因为对他有影响的子树在做之前一定在他的上面从上到下搜索的过程可以把rever做了。

但这道题要求我们输出转换之前的,因此不能保证之前的rev标记都已执行完因此就要从上到下做一遍。

By:大奕哥

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=1e5+;
  4. int fa[N],c[N][],pos[N],rev[N],mn[N],w[N],size[N],n,m,rt;
  5. struct node
  6. {
  7. int pos,v;
  8. bool operator<(const node &b)const {
  9. if(v==b.v)return pos<b.pos;
  10. return v<b.v;
  11. }
  12. }a[N];
  13. void pushdown(int x)
  14. {
  15. if(rev[x])rev[c[x][]]^=,rev[c[x][]]^=,rev[x]^=,swap(c[x][],c[x][]);
  16. mn[x]=w[x];pos[x]=x;
  17. if(mn[c[x][]]<mn[x])mn[x]=mn[c[x][]],pos[x]=pos[c[x][]];
  18. if(mn[c[x][]]<mn[x])mn[x]=mn[c[x][]],pos[x]=pos[c[x][]];
  19. size[x]=size[c[x][]]+size[c[x][]]+;
  20. }
  21. void rotate(int x,int &k)
  22. {
  23. int y=fa[x],z=fa[y];
  24. int l=(c[y][]==x);int r=l^;
  25. if(y==k)k=x;else c[z][c[z][]==y]=x;
  26. fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
  27. c[y][l]=c[x][r];c[x][r]=y;
  28. pushdown(y);pushdown(x);
  29. }
  30. int s[N],top;
  31. void splay(int x,int &k)
  32. {
  33. top=;
  34. for(int i=x;i;i=fa[i])s[++top]=i;
  35. for(int i=top;i;--i)pushdown(s[i]);
  36. while(x!=k)
  37. {
  38. int y=fa[x],z=fa[y];
  39. if(y!=k)
  40. {
  41. if(x==c[y][]^y==c[z][])rotate(x,k);
  42. else rotate(y,k);
  43. }
  44. rotate(x,k);
  45. }
  46. }
  47. int find(int x,int k)
  48. {
  49. if(!x)return ;pushdown(x);
  50. if(size[c[x][]]+==k)return x;
  51. else if(size[c[x][]]+>k)return find(c[x][],k);
  52. else return find(c[x][],k-size[c[x][]]-);
  53. }
  54. int query(int l,int r)
  55. {
  56. int x=find(rt,l),y=find(rt,r+);
  57. splay(x,rt);splay(y,c[x][]);
  58. return pos[c[y][]];
  59. }
  60. void rever(int l,int r)
  61. {
  62. int x=find(rt,l),y=find(rt,r+);
  63. splay(x,rt);splay(y,c[x][]);
  64. int z=c[y][];
  65. rev[z]^=;
  66. return;
  67. }
  68. void build(int l,int r,int f){
  69. if(l>r)return;
  70. int mid=l+r>>;
  71. fa[mid]=f;c[f][mid>=f]=mid;
  72. w[mid]=mn[mid]=a[mid].v;
  73. if(l==r)
  74. {
  75. rev[mid]=;size[mid]=;pushdown(mid);return;
  76. }
  77. build(l,mid-,mid);build(mid+,r,mid);
  78. pushdown(mid);
  79. return;
  80. }
  81. bool cmp(node aa,node bb){
  82. return aa.pos<bb.pos;
  83. }
  84. int ans[N];
  85. int main()
  86. {
  87. scanf("%d",&n);
  88. build(,n+,);rt=(n+)>>;mn[]=a[].v=a[n+].v=1e9;
  89. for(int i=;i<=n+;++i)scanf("%d",&a[i].v);
  90. for(int i=;i<=n;++i)a[i+].pos=i;
  91. sort(a+,a+n+);
  92. for(int i=;i<=n;++i)a[i+].v=i;
  93. sort(a+,a+n+,cmp);
  94. build(,n+,);
  95. rt=(n+)>>;
  96. for(int i=;i<=n;++i)
  97. {
  98. int x=query(i,n);
  99. splay(x,rt);
  100. ans[i]=size[c[x][]];
  101. rever(i,ans[i]);
  102. }
  103. for(int i=;i<n;++i)
  104. {
  105. printf("%d ",ans[i]);
  106. }
  107. printf("%d",ans[n]);
  108. return ;
  109. }

这个是标准的按照序列中的位置建树,每次splay之前要query一下。跑了3000ms,后来又在网上找了一种写法,直接按照权值建图,查找就直接splay对应的标号即可,2000ms。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=1e5+;
  4. int fa[N],c[N][],pos[N],rev[N],mn[N],w[N],size[N],n,m,rt;
  5. struct node
  6. {
  7. int pos,v;
  8. bool operator<(const node &b)const {
  9. if(v==b.v)return pos<b.pos;
  10. return v<b.v;
  11. }
  12. }a[N];
  13. bool cmp(node aa,node bb){
  14. return aa.pos<bb.pos;
  15. }
  16. void pushdown(int x)
  17. {
  18. if(rev[x])rev[c[x][]]^=,rev[c[x][]]^=,rev[x]^=,swap(c[x][],c[x][]);
  19. mn[x]=w[x];pos[x]=x;
  20. if(mn[c[x][]]<mn[x])mn[x]=mn[c[x][]],pos[x]=pos[c[x][]];
  21. if(mn[c[x][]]<mn[x])mn[x]=mn[c[x][]],pos[x]=pos[c[x][]];
  22. size[x]=size[c[x][]]+size[c[x][]]+;
  23. }
  24. void rotate(int x,int &k)
  25. {
  26. int y=fa[x],z=fa[y];
  27. int l=(c[y][]==x);int r=l^;
  28. if(y==k)k=x;else c[z][c[z][]==y]=x;
  29. fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
  30. c[y][l]=c[x][r];c[x][r]=y;
  31. pushdown(y);pushdown(x);
  32. }
  33. int s[N],top;
  34. void splay(int x,int &k)
  35. {
  36. top=;
  37. for(int i=x;i;i=fa[i])s[++top]=i;
  38. for(int i=top;i;--i)pushdown(s[i]);
  39. while(x!=k)
  40. {
  41. int y=fa[x],z=fa[y];
  42. if(y!=k)
  43. {
  44. if(x==c[y][]^y==c[z][])rotate(x,k);
  45. else rotate(y,k);
  46. }
  47. rotate(x,k);
  48. }
  49. }
  50. int find(int x,int k)
  51. {
  52. if(!x)return ;pushdown(x);
  53. if(size[c[x][]]+==k)return x;
  54. else if(size[c[x][]]+>k)return find(c[x][],k);
  55. else return find(c[x][],k-size[c[x][]]-);
  56. }
  57. void rever(int l,int r)
  58. {
  59. int x=find(rt,l),y=find(rt,r+);
  60. splay(x,rt);splay(y,c[x][]);
  61. int z=c[y][];
  62. rev[z]^=;
  63. return;
  64. }
  65. void build(int l,int r,int f){
  66. if(l>r)return;
  67. int mid=l+r>>;
  68. int now=a[mid].v,last=a[f].v;
  69. fa[now]=last;c[last][mid>=f]=now;
  70. if(l==r)
  71. {
  72. rev[now]=;size[now]=;return;
  73. }
  74. build(l,mid-,mid);build(mid+,r,mid);
  75. pushdown(now);
  76. return;
  77. }
  78. int ans[N];
  79. int main()
  80. {
  81. scanf("%d",&n);
  82. rt=(n+)>>;mn[]=1e9;
  83. for(int i=;i<=n+;++i)scanf("%d",&a[i].v);
  84. for(int i=;i<=n;++i)a[i+].pos=i;
  85. sort(a+,a+n+);
  86. for(int i=;i<=n+;++i)a[i].v=i;a[].v=;a[n+].v=n+;
  87. sort(a+,a+n+,cmp);
  88. build(,n+,);
  89. rt=a[(n+)>>].v;
  90. for(int i=;i<=n;++i)
  91. {
  92. splay(i+,rt);
  93. ans[i]=size[c[rt][]];
  94. rever(i,ans[i]);
  95. }
  96. for(int i=;i<n;++i)
  97. {
  98. printf("%d ",ans[i]);
  99. }
  100. printf("%d",ans[n]);
  101. return ;
  102. }

BZOJ1552/3506 [Cerc2007]robotic sort的更多相关文章

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

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

  2. 【BZOJ1552】[Cerc2007]robotic sort Splay

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

  3. 【BZOJ-1552&3506】robotic sort&排序机械臂 Splay

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

  4. 【bzoj1552】[Cerc2007]robotic sort

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

  5. 【BZOJ】1552/3506 [Cerc2007]robotic sort

    [算法]splay [题解] splay维护序列,用权值(离散化)作为编号.每次找第i小的话直接找对应编号splay即可. 但是这样splay没有下传翻转标记?直接暴力找到路径然后从根到改结点push ...

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

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

  7. [BZOJ1552][Cerc2007]robotic sort

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

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

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

  9. bzoj 1552: [Cerc2007]robotic sort

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

随机推荐

  1. [acmm week12]二分+dp+单调队列

    1004 抄作业         Time Limit: 1sec    Memory Limit:256MB Description Zfree虽然平时很爱学习,但是他迫于生活所迫(比如设计cpu实 ...

  2. ES6 中 Array.from() 不能得到的数组元素是 undefined 或是空数组

    本文地址:http://www.cnblogs.com/veinyin/p/7944072.html  正确格式 let json = { '0': 'Waaaa~', '1': 'Hello,', ...

  3. HDU 5914 Triangle 斐波纳契数列 && 二进制切金条

    HDU5914 题目链接 题意:有n根长度从1到n的木棒,问最少拿走多少根,使得剩下的木棒无论怎样都不能构成三角形. 题解:斐波纳契数列,a+b=c恰好不能构成三角形,暴力就好,推一下也可以. #in ...

  4. 2017ACM暑期多校联合训练 - Team 5 1006 HDU 5205 Rikka with Graph (找规律)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...

  5. 在mac上安装ruby

    1.先装RVM,一个多版本ruby环境的管理和切换工具 curl -sSL https://get.rvm.io | bash -s stable 会自动装上最新版.更新RVM版本:$ rvm get ...

  6. Django之ModelForm(二)-----ModelForm组件

    a.  class Meta:             model,                           # 对应Model的             fields=None,     ...

  7. How to read source code[repost]

    https://github.com/benjycui/benjycui.github.io/blob/master/posts/how-to-read-open-source-javascript- ...

  8. Tornado/Python 学习笔记(一)

    1.源代码下载及安装:http://www.tornadoweb.org/en/stable/ 2.python中xmlrpc库官方文档:https://docs.python.org/3/libra ...

  9. skb_reserve(skb,2)中的2的意义

    skb_reserve() skb_reserve()在数据缓存区头部预留一定的空间,通常被用来在数据缓存区中插入协议首部或者在某个边界上对齐.它并没有把数据移出或移入数据缓存区,而只是简单地更新了数 ...

  10. Activity工作流 -- java运用

    一. 什么是工作流 以请假为例,现在大多数公司的请假流程是这样的 员工打电话(或网聊)向上级提出请假申请——上级口头同意——上级将请假记录下来——月底将请假记录上交公司——公司将请假录入电脑 采用工作 ...