[关闭]
@wsndy-xx 2018-05-07T23:51:17.000000Z 字数 1803 阅读 893

Luogu 文艺平衡树(Splay)

题解


题意

一段序列,每次翻转一段区间,输出最后的序列


显然要维护下标,不可以维护 key[], 然而在这道题中应该是一样的
首先将 1 - n 插入平衡树
将区间 [l, r] 进行翻转考虑如何操作
找到 l 的前驱 pre, 也就是下标为 l - 1 的数,将 pre Rotate 到根
找到 r 的后继 nxt, 也就是下标为 r + 1 的数,将 nxt Rotate 到根的儿子(右儿子)
此时 nxt 的左子树就是区间 [l, r]
对区间打旋转标记
以后用到该节点就要下放旋转标记
就可以完美的解决这道题


Code

  1. #include <bits/stdc++.h>
  2. const int N = 1e5 + 10;
  3. const int oo = 1e9;
  4. int Root, Size, ch[N][2], fa[N], size[N], flag[N], key[N], A[N];
  5. int n, T;
  6. #define gc getchar()
  7. inline int read() {
  8. int x = 0; char c = gc;
  9. while(c < '0' || c > '9') c = gc;
  10. while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
  11. return x;
  12. }
  13. void Update(int x) {size[x] = size[ch[x][1]] + size[ch[x][0]] + 1;}
  14. bool Get(int x) {return x == ch[fa[x]][1];}
  15. void Pushup(int x) {
  16. if(x && flag[x]) {
  17. flag[ch[x][1]] ^= 1;
  18. flag[ch[x][0]] ^= 1;
  19. std:: swap(ch[x][1], ch[x][0]);
  20. flag[x] = 0;
  21. }
  22. }
  23. void Rotate(int x) {
  24. Pushup(fa[x]);
  25. Pushup(x);
  26. int fax = fa[x], grfa = fa[fax], w = Get(x);
  27. ch[fax][w] = ch[x][w ^ 1];
  28. fa[ch[x][w ^ 1]] = fax;
  29. ch[x][w ^ 1] = fax;
  30. fa[fax] = x;
  31. fa[x] = grfa;
  32. ch[grfa][ch[grfa][1] == fax] = x;
  33. Update(x);
  34. Update(fax);
  35. }
  36. void Splay(int x, int y) {
  37. for(int fax = 1; (fax = fa[x]) && (fax != y); Rotate(x))
  38. if(fa[fax] != y)
  39. Rotate((Get(fax) == Get(x)) ? fax : x);
  40. if(!y) Root = x;
  41. }
  42. void Insert(int x) {
  43. if(!Size) {
  44. Size ++;
  45. Root = 1;
  46. size[Root] = 1;
  47. key[Root] = x;
  48. return ;
  49. }
  50. int now = Root, fanow = 0;
  51. while(1) {
  52. fanow = now;
  53. now = ch[now][x > key[fanow]];
  54. if(!now) {
  55. Size ++;
  56. ch[fanow][x > key[fanow]] = Size;
  57. key[Size] = x;
  58. fa[Size] = fanow;
  59. size[Size] = 1;
  60. Update(fanow);
  61. Splay(Size, 0);
  62. break;
  63. }
  64. }
  65. }
  66. inline int Find(int x) {
  67. int now = Root;
  68. while(1) {
  69. Pushup(now);
  70. if(x <= size[ch[now][0]]) now = ch[now][0];
  71. else {
  72. x -= size[ch[now][0]] + 1;
  73. if(!x) return now;
  74. now = ch[now][1];
  75. }
  76. }
  77. }
  78. void Dfs(int x) {
  79. Pushup(x);
  80. if(ch[x][0]) Dfs(ch[x][0]);
  81. if(key[x] != oo && key[x] != - oo) std:: cout << key[x] << " ";
  82. if(ch[x][1]) Dfs(ch[x][1]);
  83. }
  84. int main() {
  85. n = read(); T = read();
  86. A[1] = - oo; A[n + 2] = oo;
  87. for(int i = 1; i <= n; i ++) A[i + 1] = i;
  88. for(int i = 1; i <= n + 2; i ++) Insert(A[i]);
  89. Splay(1, 0);
  90. for(; T; T --) {
  91. int l = read(), r = read();
  92. int pre = Find(l), nxt = Find(r + 2);
  93. Splay(pre, 0), Splay(nxt, pre);
  94. flag[ch[nxt][0]] ^= 1;
  95. }
  96. Dfs(Root);
  97. return 0;
  98. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注