Luzhiled's Library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub ei1333/library

:heavy_check_mark: Splay-Tree-Base(Splay木) (structure/develop/splay-tree-base.hpp)

Verified with

Code

/**
 * @brief Splay-Tree-Base(Splay木)
 */
template< typename Node >
struct SplayTreeBase {
public:
  using NP = Node *;

  bool is_root(const NP &t) const { return !t->p || (t->p->l != t && t->p->r != t); }

  inline size_t count(const NP &t) const { return t ? t->sz : 0; }

  void splay(NP t) {
    push(t);
    while(!is_root(t)) {
      auto *q = t->p;
      if(!is_root(t)) {
        push(q), push(t);
        if(q->l == t) rotr(t);
        else rotl(t);
      } else {
        auto *r = q->p;
        push(r), push(q), push(t);
        if(r->l == q) {
          if(q->l == t) rotr(q), rotr(t);
          else rotl(t), rotr(t);
        } else {
          if(q->r == t) rotl(q), rotl(t);
          else rotr(t), rotl(t);
        }
      }
    }
  }

  NP erase(NP t) {
    splay(t);
    Node *x = t->l, *y = t->r;
    delete t;
    if(!x) {
      t = y;
      if(t) t->p = nullptr;
    } else if(!y) {
      t = x;
      t->p = nullptr;
    } else {
      x->p = nullptr;
      t = get_right(x);
      splay(t);
      t->r = y;
      y->p = t;
    }
    return t;
  }

  NP splay_front(NP t) {
    splay(t);
    while(t->l) t = t->l;
    splay(t);
    return t;
  }

  NP splay_back(NP t) {
    splay(t);
    while(t->r) t = t->r;
    splay(t);
    return t;
  }

  pair< NP, NP > split(NP t, int k) {
    if(!t) return {nullptr, nullptr};
    push(t);
    if(k <= count(t->l)) {
      auto x = split(t->l, k);
      t->l = x.second;
      t->p = nullptr;
      if(x.second) x.second->p = t;
      return {x.first, update(t)};
    } else {
      auto x = split(t->r, k - count(t->l) - 1);
      t->r = x.first;
      t->p = nullptr;
      if(x.first) x.first->p = t;
      return {update(t), x.second};
    }
  }

  template< typename... Args >
  NP merge(NP p, Args... args) {
    return merge(p, merge(args...));
  }

  NP merge(NP l, NP r) {
    if(!l && !r) return nullptr;
    if(!l) return splay(r), r;
    if(!r) return splay(l), l;
    splay(l), splay(r);
    l = splay_back(l);
    l->r = r;
    r->p = l;
    update(l);
    return l;
  }

  tuple< NP, NP, NP > split3(NP t, int a, int b) {
    splay(t);
    auto x = split(t, a);
    auto y = split(x.second, b - a);
    return make_tuple(x.first, y.first, y.second);
  }

  virtual void push(NP t) = 0;

  virtual Node *update(NP t) = 0;

private:

  void rotr(NP t) {
    auto *x = t->p, *y = x->p;
    if((x->l = t->r)) t->r->p = x;
    t->r = x, x->p = t;
    update(x), update(t);
    if((t->p = y)) {
      if(y->l == x) y->l = t;
      if(y->r == x) y->r = t;
      update(y);
    }
  }

  void rotl(NP t) {
    auto *x = t->p, *y = x->p;
    if((x->r = t->l)) t->l->p = x;
    t->l = x, x->p = t;
    update(x), update(t);
    if((t->p = y)) {
      if(y->l == x) y->l = t;
      if(y->r == x) y->r = t;
      update(y);
    }
  }

  NP build(int l, int r, const vector< NP > &v) {
    if(l + 1 >= r) return v[l];
    return merge(build(l, (l + r) >> 1, v), build((l + r) >> 1, r, v));
  }

protected:

  NP build_node(const vector< NP > &v) {
    return build(0, v.size(), v);
  }

  NP insert_node(NP t, int k, NP v) {
    splay(t);
    auto x = split(t, k);
    return merge(x.first, v, x.second);
  }

  NP erase_node(NP t, int k) {
    splay(t);
    auto x = split(t, k);
    auto y = split(x.second, 1);
    delete y.first;
    return merge(x.first, y.second);
  }
};
#line 1 "structure/develop/splay-tree-base.hpp"
/**
 * @brief Splay-Tree-Base(Splay木)
 */
template< typename Node >
struct SplayTreeBase {
public:
  using NP = Node *;

  bool is_root(const NP &t) const { return !t->p || (t->p->l != t && t->p->r != t); }

  inline size_t count(const NP &t) const { return t ? t->sz : 0; }

  void splay(NP t) {
    push(t);
    while(!is_root(t)) {
      auto *q = t->p;
      if(!is_root(t)) {
        push(q), push(t);
        if(q->l == t) rotr(t);
        else rotl(t);
      } else {
        auto *r = q->p;
        push(r), push(q), push(t);
        if(r->l == q) {
          if(q->l == t) rotr(q), rotr(t);
          else rotl(t), rotr(t);
        } else {
          if(q->r == t) rotl(q), rotl(t);
          else rotr(t), rotl(t);
        }
      }
    }
  }

  NP erase(NP t) {
    splay(t);
    Node *x = t->l, *y = t->r;
    delete t;
    if(!x) {
      t = y;
      if(t) t->p = nullptr;
    } else if(!y) {
      t = x;
      t->p = nullptr;
    } else {
      x->p = nullptr;
      t = get_right(x);
      splay(t);
      t->r = y;
      y->p = t;
    }
    return t;
  }

  NP splay_front(NP t) {
    splay(t);
    while(t->l) t = t->l;
    splay(t);
    return t;
  }

  NP splay_back(NP t) {
    splay(t);
    while(t->r) t = t->r;
    splay(t);
    return t;
  }

  pair< NP, NP > split(NP t, int k) {
    if(!t) return {nullptr, nullptr};
    push(t);
    if(k <= count(t->l)) {
      auto x = split(t->l, k);
      t->l = x.second;
      t->p = nullptr;
      if(x.second) x.second->p = t;
      return {x.first, update(t)};
    } else {
      auto x = split(t->r, k - count(t->l) - 1);
      t->r = x.first;
      t->p = nullptr;
      if(x.first) x.first->p = t;
      return {update(t), x.second};
    }
  }

  template< typename... Args >
  NP merge(NP p, Args... args) {
    return merge(p, merge(args...));
  }

  NP merge(NP l, NP r) {
    if(!l && !r) return nullptr;
    if(!l) return splay(r), r;
    if(!r) return splay(l), l;
    splay(l), splay(r);
    l = splay_back(l);
    l->r = r;
    r->p = l;
    update(l);
    return l;
  }

  tuple< NP, NP, NP > split3(NP t, int a, int b) {
    splay(t);
    auto x = split(t, a);
    auto y = split(x.second, b - a);
    return make_tuple(x.first, y.first, y.second);
  }

  virtual void push(NP t) = 0;

  virtual Node *update(NP t) = 0;

private:

  void rotr(NP t) {
    auto *x = t->p, *y = x->p;
    if((x->l = t->r)) t->r->p = x;
    t->r = x, x->p = t;
    update(x), update(t);
    if((t->p = y)) {
      if(y->l == x) y->l = t;
      if(y->r == x) y->r = t;
      update(y);
    }
  }

  void rotl(NP t) {
    auto *x = t->p, *y = x->p;
    if((x->r = t->l)) t->l->p = x;
    t->l = x, x->p = t;
    update(x), update(t);
    if((t->p = y)) {
      if(y->l == x) y->l = t;
      if(y->r == x) y->r = t;
      update(y);
    }
  }

  NP build(int l, int r, const vector< NP > &v) {
    if(l + 1 >= r) return v[l];
    return merge(build(l, (l + r) >> 1, v), build((l + r) >> 1, r, v));
  }

protected:

  NP build_node(const vector< NP > &v) {
    return build(0, v.size(), v);
  }

  NP insert_node(NP t, int k, NP v) {
    splay(t);
    auto x = split(t, k);
    return merge(x.first, v, x.second);
  }

  NP erase_node(NP t, int k) {
    splay(t);
    auto x = split(t, k);
    auto y = split(x.second, 1);
    delete y.first;
    return merge(x.first, y.second);
  }
};
Back to top page