题目大意:给出1到n的有序数列,现在有两个操作:

1.CUT a b c 把第a到第b个数剪切下来,放到剩下的第c个数的后边。

2.FLIP a b  把第a到第b个数反转。

经过总共m次操作后,求现在的数列。

n,m<300000

分析:典型的splay题。包含的操作即:查找第k大,剪切,插入,反转等操作。

维护size,rev(反转标记)即可。

通过size可以找到第k大,通过rev做懒标记,可以进行反转。

具体说就是,比如要剪切CUT a,b,c,以先把第a-1个节点splay到根的位置,然后把第b+1个节点spaly到根的右儿子的位置,则a到b这一段就刚好是根的右儿子的左子树了,然后把它剪切下来。再把第c节点splay到根的位置,把第c+1个节点splay到根的右儿子的位置,再把刚才剪切的那一段接在根的右儿子的左儿子位置即可。FLIP a b的话,先把第a-1个节点splay到根的位置,把第b+1个节点splay到根的右儿子的位置,然后对根的右儿子的左子树打上懒标记即可。注意:打蓝标记应该是tree[i].rev^=1,而不是tree[i].rev=1。我就是这样wa了一次。

因为splay树的伸展特性,splay树中要增加两个额外的虚拟节点,即头节点和尾节点。初始时把头结点作为根节点,把尾节点作为根的右儿子。有效节点作为根的左儿子的右子树。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. using namespace std;
  5. #define MAXN 300505
  6. int tot,root,n,m,a,b,c;
  7. char str[];
  8. struct node
  9. {
  10. int val,fa,sz;
  11. bool rev;
  12. int ch[];
  13. }tree[MAXN];
  14. void newnode(int &r,int father,int val)
  15. {
  16. tot++;
  17. r=tot;
  18. tree[tot].fa=father;
  19. tree[tot].val=val;
  20. }
  21. void build(int &root,int l,int r,int father)
  22. {
  23. if(l>r)return;
  24. int mid=(l+r)/;
  25. newnode(root,father,mid);
  26. build(tree[root].ch[],l,mid-,root);
  27. build(tree[root].ch[],mid+,r,root);
  28. tree[root].sz=tree[tree[root].ch[]].sz+tree[tree[root].ch[]].sz+;
  29. }
  30. void init()
  31. {
  32. tot=root=;
  33. memset(tree,,sizeof tree);
  34. newnode(root,,-);
  35. newnode(tree[root].ch[],root,-);
  36. build(tree[tree[].ch[]].ch[],,n,tree[].ch[]);
  37. tree[tree[].ch[]].sz=tree[tree[tree[].ch[]].ch[]].sz+;
  38. tree[].sz=tree[tree[].ch[]].sz+;
  39. }
  40. void pd(int &r)
  41. {
  42. if(tree[r].rev==)
  43. {swap(tree[r].ch[],tree[r].ch[]);
  44. tree[tree[r].ch[]].rev^=;
  45. tree[tree[r].ch[]].rev^=;
  46. tree[r].rev=;
  47. }
  48.  
  49. }
  50. void pu(int &r)
  51. {
  52. tree[r].sz=tree[tree[r].ch[]].sz+tree[tree[r].ch[]].sz+;
  53. }
  54. void rotato(int &r,bool kind)
  55. {
  56. int y=tree[r].fa;
  57. int yy=tree[y].fa;
  58. if(yy)
  59. {
  60. tree[yy].ch[tree[yy].ch[]==y]=r;
  61. }
  62. tree[r].fa=yy;
  63. tree[tree[r].ch[kind]].fa=y;
  64. tree[y].ch[!kind]=tree[r].ch[kind];
  65. tree[y].fa=r;
  66. tree[r].ch[kind]=y;
  67. pu(y);
  68. pu(r);
  69. }
  70. void splay(int &r,int goal)
  71. {
  72. while(tree[r].fa!=goal)
  73. {
  74. int y=tree[r].fa;
  75. int yy=tree[y].fa;
  76. if(yy==goal)rotato(r,tree[y].ch[]==r);
  77. else
  78. {
  79. int kind=(tree[y].ch[]==r);
  80. if(tree[yy].ch[kind]==y)
  81. {
  82. rotato(r,kind);
  83. rotato(r,!kind);
  84. }
  85. else
  86. {
  87. rotato(y,kind);
  88. rotato(r,kind);
  89. }
  90. }
  91. }
  92. if(goal==)
  93. root=r;
  94. }
  95. int find(int r,int k)
  96. {
  97. pd(r);
  98. if(tree[tree[r].ch[]].sz==k-)
  99. return r;
  100. else if(tree[tree[r].ch[]].sz>k-)
  101. return find(tree[r].ch[],k);
  102. else return find(tree[r].ch[],k-tree[tree[r].ch[]].sz-);
  103. }
  104. void print(int &r)
  105. {
  106. pd(r);
  107. if(tree[r].ch[])
  108. print(tree[r].ch[]);
  109. if(tree[r].val!=-){printf("%d",tree[r].val);if(tot>)printf(" ");tot--;}
  110. if(tree[r].ch[])
  111. print(tree[r].ch[]);
  112. }
  113. int main()
  114. {
  115.  
  116. while(scanf("%d%d",&n,&m)&&(n>=&&m>=))
  117. {
  118. init();
  119. for(int i=;i<m;i++)
  120. {
  121. scanf("%s",str);
  122. if(str[]=='C')
  123. {
  124. scanf("%d%d%d",&a,&b,&c);
  125. int x1=find(root,a);
  126. int y1=find(root,b+);
  127. splay(x1,);
  128. splay(y1,root);
  129. int t=tree[tree[root].ch[]].ch[];
  130. tree[tree[root].ch[]].ch[]=;
  131. pu(tree[root].ch[]);
  132. pu(root);
  133. x1=find(root,c+);
  134. y1=find(root,c+);
  135. splay(x1,);
  136. splay(y1,root);
  137. tree[tree[root].ch[]].ch[]=t;
  138. tree[t].fa=tree[root].ch[];
  139. pu(tree[root].ch[]);
  140. pu(root);
  141. }
  142. else
  143. {
  144. scanf("%d%d",&a,&b);
  145. int x=find(root,a);
  146. int y=find(root,b+);
  147. splay(x,);
  148. splay(y,root);
  149. tree[tree[tree[root].ch[]].ch[]].rev^=;
  150. }
  151. }
  152. print(root);
  153. printf("\n");
  154. }
  155. }

HDU3487 play with chain的更多相关文章

  1. HDU--3487 Play with Chain (Splay伸展树)

    Play with Chain Problem Description YaoYao is fond of playing his chains. He has a chain containing ...

  2. HDU3487 Play With Chain [Splay]

    题目传送门 题目描述 Problem Description YaoYao is fond of playing his chains. He has a chain containing n dia ...

  3. HDU3487 Play with Chain splay 区间反转

    HDU3487 splay最核心的功能是将平衡树中的节点旋转到他的某个祖先的位置,并且维持平衡树的性质不变. 两个操作(数组实现) cut l,r, c把[l,r]剪下来放到剩下序列中第c个后面的位置 ...

  4. HDU-3487 Play with Chain Splay tee区间反转,移动

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487 对于一个数列有两种操作:1.CUT a b c,先取出a-b区间的数,然后把它们放在取出后的第c ...

  5. 【HDU3487】【splay分裂合并】Play with Chain

    Problem Description YaoYao is fond of playing his chains. He has a chain containing n diamonds on it ...

  6. HDU 3487 Play with Chain | Splay

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  7. hdu3487 splay树

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  8. HDU 3487 Play with Chain (splay tree)

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  9. STM32用JLINK 烧写程序时出现NO Cortex-m device found in JTAG chain现象和解决方案

    现象 CPU: STM32107VC 用JLINK 烧写程序时出现NO Cortex-m device found in JTAG chain 如图无法查找到硬件就是CPU 提示1:NO Cortex ...

随机推荐

  1. 51nod 1135 原根

    题目链接:51nod 1135 原根 设 m 是正整数,a是整数,若a模m的阶等于φ(m),则称 a 为 模m的一个原根.(其中φ(m)表示m的欧拉函数) 阶:gcd(a,m)=1,使得成立的最小的 ...

  2. MVC5 + EF6 入门完整教程一:从0开始

    第0课 从0开始 ASP.NET MVC开发模式和传统的WebForm开发模式相比,增加了很多"约定". 直接讲这些 "约定" 会让人困惑,而且东西太多容易忘记 ...

  3. 安装Pod时提示ERROR: While executing gem ... (Errno::EPERM) Operation not permitted - /usr/bin/pod

    环境:OSX EI 10.11.1 昨天切换gem源后,招待pod安装没有任何问题,也可以正常用$ gem sources --add https://ruby.taobao.org/ --remov ...

  4. iOS开发拓展篇—音频处理(音乐播放器5)

    iOS开发拓展篇—音频处理(音乐播放器5) 实现效果: 一.半透明滑块的设置 /** *拖动滑块 */ - (IBAction)panSlider:(UIPanGestureRecognizer *) ...

  5. codeforces 451E Devu and Flowers

    题意:有n个瓶子每个瓶子有 f[i] 支相同的颜色的花(不同瓶子颜色不同,相同瓶子花视为相同) 问要取出s支花有多少种不同方案. 思路: 如果每个瓶子的花有无穷多.那么这个问题可以转化为  s支花分到 ...

  6. sscanf函数

    sscanf函数用法举例 #include <stdio.h> #include <string.h> #define N 512 int main() { char buf[ ...

  7. Documentum常见问题11-xplore全文检索时找不到相关内容

    最近帮助同事处理了一个关于全文检索的问题,随手记录下来供以后参考. 问题一 某些Cabinet下的文件可以全文检索到,但某些Cabinet下的数据全文检索不成功. 新建了一个Docbase-AADCT ...

  8. 使用rpm命令卸载程序

    步骤1.rpm -qa|grep 程序名称 步骤2.rpm -e 安装包名称 --nodeps

  9. 在mahout安装目录下输入mahout 提示 ERROR: Could not find mahout-examples-*.job

    错误:ERROR: Could not find mahout-examples-*.job in /home/grid/mahout-distribution-0.8 or /home/grid/m ...

  10. php 判断复选框checkbox是否被选中

    php 判断复选框checkbox是否被选中   复选框checkbox在php表单提交中经常被使用到,本文章通过实例向大家介绍php如何判断复选框checkbox中的值是否被选中,需要的朋友可以参考 ...