Treap.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Cartesian tree (treap)
  2. // Compute sum (here) of a range, and can reverse a range
  3. // COMPLEXITY on average : construction O(nlog n)?, operations O(log n), lazy reversal
  4. // all ranges are 1-based
  5. struct Node {
  6. int y, sz;
  7. long long v, sm;
  8. bool rev;
  9. struct Node *l, *r;
  10. Node(long long v) : v(v) {
  11. y = rand();
  12. sm = v;
  13. rev = false;
  14. sz = 1;
  15. l = r = NULL;
  16. }
  17. };
  18. typedef struct Node Node;
  19. int size(Node *n) {
  20. return n != NULL ? n->sz : 0;
  21. }
  22. long long sum(Node *n) {
  23. return n != NULL ? n->sm : 0;
  24. }
  25. void update(Node *n) {
  26. if(n != NULL) {
  27. n->sm = n->v + sum(n->l) + sum(n->r);
  28. n->sz = 1 + size(n->l) + size(n->r);
  29. }
  30. }
  31. void push(Node *n) { // push reverse flag
  32. if(n != NULL && n->rev) {
  33. swap(n->l, n->r);
  34. n->rev = false;
  35. if(n->l != NULL)
  36. n->l->rev ^= true;
  37. if(n->r != NULL)
  38. n->r->rev ^= true;
  39. }
  40. }
  41. void merge(Node* &n, Node *l, Node *r) {
  42. push(l); push(r);
  43. if(l == NULL) {
  44. n = r; return;
  45. }
  46. if(r == NULL) {
  47. n = l; return;
  48. }
  49. if(l->y > r->y) {
  50. merge(l->r, l->r, r);
  51. n = l;
  52. }
  53. else {
  54. merge(r->l, l, r->l);
  55. n = r;
  56. }
  57. update(n);
  58. }
  59. // x stays in r
  60. void split(Node *n, Node* &l, Node* &r, int x, int add = 0) {
  61. push(n);
  62. if(n == NULL) {
  63. l = r = NULL; return;
  64. }
  65. int key = size(n->l) + 1 + add;
  66. if(x <= key) {
  67. split(n->l, l, n->l, x, add);
  68. r = n;
  69. }
  70. else {
  71. split(n->r, n->r, r, x, key);
  72. l = n;
  73. }
  74. update(n);
  75. }
  76. // reverse [l, r] (1-based)
  77. void reverse(Node* &n, int l, int r) {
  78. Node *a, *b;
  79. split(n, n, a, l, 0);
  80. split(a, a, b, r - l + 2, 0);
  81. a->rev ^= true;
  82. merge(n, n, a);
  83. merge(n, n, b);
  84. }
  85. // query sum of [l, r] (1-based)
  86. long long query(Node* &n, int l, int r) {
  87. long long ans;
  88. Node *a, *b;
  89. split(n, n, a, l, 0);
  90. split(a, a, b, r - l + 2, 0);
  91. ans = sum(a);
  92. merge(n, n, a);
  93. merge(n, n, b);
  94. return ans;
  95. }
  96. // insert value v at position p (if p <= size, at the end if p > size)
  97. void insert(Node* &n, int p, long long v) {
  98. Node *a;
  99. split(n, n, a, p);
  100. merge(n, n, new Node(v));
  101. merge(n, n, a);
  102. }
  103. // delete element at position p (if any)
  104. void del(Node* &n, int p) {
  105. Node *a, *b;
  106. split(n, n, a, p);
  107. split(a, a, b, 2);
  108. merge(n, n, b);
  109. if(a)
  110. delete a;
  111. }