传送门:>Here<

解法分析

  用splay来维护这个序列。

  一直没有搞明白的是,这里的splay的节点究竟维护的是什么?是权值吗?肯定不是,因为区间是会翻转的,如果维护权值的话很快平衡树就不再满足性质。

  然而从头到尾,唯一始终统一的就是位置——始终是1~n. 因此考虑用节点来维护位置。

  这样在维护splay的时候,翻转一段区间就相当于修改了这一段区间的位置,使原来小的现在大了,原来大的现在小了。放在树上形象的看,就是原来作为父节点的左儿子的统统称为了右儿子。反之亦然。因此只要找出连续的那一段区间,并且翻转左右子树即可。注意为了减少操作次数,可以打懒标记。

  如何找出连续的那一段目标区间?由于要翻转的是区间$[l, r]$,我们可以找到位置(注意,这里的位置也就是平衡树维护的权值的排名了,因此位置i也就是排名第i的)l-1和r+1的点,分别旋转到根节点和根节点的右子树上。这样,根节点的右子节点的左子树就是这段区间了。(想一想,为什么)。特殊的,当边界到达1或n时会溢出,因此我们加入哨兵节点-1和n+1。这样位置i就是排名i+1了。

  值得注意的是何时下传懒标记——根据懒标记的优良传统,不用就不翻转。那唯一要用的时候就是询问位置的时候了,因此只要find的时候下传就可以了。另外翻转两次相当于不翻转,所以用xor1会很方便。

  

  1. /*By QiXingzhi*/
  2. #include <cstdio>
  3. #include <queue>
  4. #include <cstring>
  5. #include <algorithm>
  6. #define r read()
  7. #define Max(a,b) (((a)>(b)) ? (a) : (b))
  8. #define Min(a,b) (((a)<(b)) ? (a) : (b))
  9. using namespace std;
  10. typedef long long ll;
  11. const int MAXN = ;
  12. const int INF = ;
  13. inline int read(){
  14. int x = ; int w = ; register int c = getchar();
  15. while(c ^ '-' && (c < '' || c > '')) c = getchar();
  16. if(c == '-') w = -, c = getchar();
  17. while(c >= '' && c <= '') x = (x << ) +(x << ) + c - '', c = getchar();
  18. return x * w;
  19. }
  20. int n,m,L,R;
  21. struct Splay{
  22. int ch[MAXN][],size[MAXN],val[MAXN],fa[MAXN],tag[MAXN],num_node,root;
  23. inline bool Son(int f, int x){
  24. return ch[f][]==x;
  25. }
  26. inline void Update(int x){
  27. size[x] = size[ch[x][]] + size[ch[x][]] + ;
  28. }
  29. inline void Rotate(int x){
  30. int f = fa[x], gf = fa[f];
  31. bool p = Son(f, x), q = !p;
  32. ch[f][p] = ch[x][q];
  33. fa[ch[x][q]] = f;
  34. ch[x][q] = f;
  35. fa[f] = x;
  36. fa[x] = gf;
  37. if(gf != ){
  38. ch[gf][Son(gf,f)] = x;
  39. }else{
  40. root = x;
  41. }
  42. Update(x), Update(f);
  43. }
  44. inline void splay(int x, int target){
  45. while(fa[x] != target){
  46. int f = fa[x], gf = fa[f];
  47. if(gf == target){
  48. Rotate(x);
  49. return;
  50. }
  51. if(Son(gf,f) == Son(f,x)){
  52. Rotate(f), Rotate(x);
  53. }
  54. else{
  55. Rotate(x), Rotate(x);
  56. }
  57. }
  58. }
  59. inline void Insert(int v){
  60. if(root == ){
  61. ++num_node;
  62. root = num_node;
  63. size[num_node] = ;
  64. val[num_node] = v;
  65. return;
  66. }
  67. for(int x = root; x != ; x = ch[x][v >= val[x]]){
  68. bool b = v >= val[x];
  69. if(ch[x][b] == ){
  70. ++num_node;
  71. ch[x][b] = num_node;
  72. size[num_node] = ;
  73. val[num_node] = v;
  74. fa[ch[x][b]] = x;
  75. splay(ch[x][b], );
  76. }
  77. }
  78. }
  79. inline void Pushdown(int x){
  80. if(x == ) return;
  81. if(!tag[x]) return;
  82. int tmp = ch[x][];
  83. ch[x][] = ch[x][];
  84. ch[x][] = tmp;
  85. tag[x] = ;
  86. tag[ch[x][]] ^= ;
  87. tag[ch[x][]] ^= ;
  88. }
  89. inline int Find(int _k){
  90. int x = root;
  91. for(; x != ;){
  92. Pushdown(x);
  93. if(size[ch[x][]] + == _k){
  94. return x;
  95. }
  96. if(size[ch[x][]] >= _k){
  97. x = ch[x][];
  98. }
  99. else{
  100. _k -= size[ch[x][]] + ;
  101. x = ch[x][];
  102. }
  103. }
  104. }
  105. inline void Reverse(int L, int R){
  106. if(L >= R) return;
  107. splay(Find(L), );
  108. splay(Find(R), root);
  109. tag[ch[ch[root][]][]] ^= ;
  110. }
  111. inline void DEBUG(){
  112. for(int i = ; i <= n; ++i){
  113. printf("%d-->%d lson:%d rson:%d\n",i,val[i],ch[i][],ch[i][]);
  114. }
  115. }
  116. }qxz;
  117. int main(){
  118. // freopen(".in","r",stdin);
  119. n=r, m=r;
  120. qxz.Insert(-);
  121. qxz.Insert(n+);
  122. for(int i = ; i <= n; ++i){
  123. qxz.Insert(i);
  124. }
  125. // qxz.DEBUG();
  126. for(int i = ; i <= m; ++i){
  127. L=r, R=r;
  128. qxz.Reverse(L,R+);
  129. }
  130. for(int i = ; i <= n; ++i){
  131. printf("%d ", qxz.val[qxz.Find(i+)]);
  132. }
  133. return ;
  134. }

「Splay」区间翻转的更多相关文章

  1. 「NOI2016」区间 解题报告

    「NOI2016」区间 最近思维好僵硬啊... 一上来就觉得先把区间拆成两个端点进行差分,然后扫描位置序列,在每个位置维护答案,用数据结构维护当前位置的区间序列,但是不会维护. 于是想研究性质,想到为 ...

  2. 「SDOI2005」区间

    「SDOI2005」区间 传送门 记录每一个位置作为左端点和右端点的出现次数,然后直接考虑差分即可. 参考代码: #include <cstdio> #define rg register ...

  3. bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2202  Solved: 1226[Submit][Sta ...

  4. BZOJ 3223: Tyvj 1729 文艺平衡树-Splay树(区间翻转)模板题

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 6881  Solved: 4213[Submit][Sta ...

  5. 【模板】文艺平衡树(Splay) 区间翻转 BZOJ 3223

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 N,M<= ...

  6. splay(1区间翻转区间最值与区间修改)

    bzoj1251权限题 题目点这里,你懂得 直接上板子,这个要好好体会 操作是最经典的. #include <algorithm> #include <iostream> #i ...

  7. hdu1890 splay维护区间翻转

    这题的建模有点不太一样,是按结点横坐标赋予键值的 同时每次rotate和splay时都要注意下往上往下更新 /* 先建立好splay tree,将结点按num/输入顺序排序,遍历时每次将当前结点提到根 ...

  8. 「Splay」普通平衡树模板

    口诀: $rotate$:先上再下,最后自己 $splay$:祖父未到旋两次,三点一线旋父亲,三点折线旋自己. $delete$:没有儿子就删光.单个儿子删自己.两个儿子找前驱. 易错点: $rota ...

  9. LOJ#2086. 「NOI2016」区间

    $n \leq 500000$个区间,从中挑出一些,使得至少有一个点被$m$个选中区间包含,且选中区间长度的极差最小. 区间题死脑筋晚期:把区间按左端点排序,然后右端点用个优先队列来弹,然后需要维护下 ...

随机推荐

  1. 纯手写AJAX

    function ajax(){ //http相应对象 var xmlhttp; //判断浏览器 if(window.XMLHttpRequest){ xmlhttp = new XMLHttpReq ...

  2. 平均精度均值(mAP)——目标检测模型性能统计量

    在机器学习领域,对于大多数常见问题,通常会有多个模型可供选择.当然,每个模型会有自己的特性,并会受到不同因素的影响而表现不同. 每个模型的好坏是通过评价它在某个数据集上的性能来判断的,这个数据集通常被 ...

  3. C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - 严格的用户账户审核功能

    整个集团有几万个用户,一个个用户添加是不现实的,只有每个公司的系统管理员添加.或者用户申请帐户,然后有相应的管理员审核,才会更准确一些. 每个公司.分公司.部门的账户情况只有所在公司的管理员是最清楚的 ...

  4. vuex状态管理工具

    父子组件之间的通信  props传递  父 向子单向传递:且每次 父组件更新时  子组件的props会跟着更新: 如果需要 子组件把数据传递给父组件,就需要在子组件上绑定自定事件 在子组件使用this ...

  5. 牛客练习赛35 C.函数的魔法

    链接 [https://ac.nowcoder.com/acm/contest/32] 题意 题目描述 一位客人来到了此花亭,给了女服务员柚一个数学问题:我们有两个函数,F(X)函数可以让X变成(XX ...

  6. Day4 Python基础之数据类型(三)

    计算机中,一切皆为对象 世界万物,皆为对象,一切对象皆可分类 ------------------------------------我是分割线---------------------------- ...

  7. CRM系统(第二部分)

      阅读目录 一.讲师与学生简介 二. 初始化 ,studyrecord, 三.初始化 course_record:批量生成学习记录 四. 考勤  url跳转 五.录入成绩 六.highcharts表 ...

  8. 【学习总结】GirlsInAI ML-diary day-4:变量/Variable

    [学习总结]GirlsInAI ML-diary 总 原博github链接-day4 变量/Variable 变量是计算机编程中一个很基础的概念,在计算机程序中,variables are reser ...

  9. Nginx Configuring HTTPS servers

    Configuring HTTPS servershttp://nginx.org/en/docs/http/configuring_https_servers.html Configuring HT ...

  10. 单个源文件下CmakeList.txt

    单个源文件下CmakeList.txt 1. main.c代码 & CmakeLists.txt 文件内容 在任意自己选定的目录下(t1/)编写main.c 与 CmakeLists.txt ...