cp_library

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

View the Project on GitHub SSRS-cp/cp_library

:warning: old_Data_Structures/Treap.cpp

Code

template <typename T>
struct treap{
  int N;
  T E;
  function<T(T, T)> f;
  vector<T> node;
  vector<T> prod;
  vector<int> priority;
  vector<int> parent;
  vector<int> left, right;
  vector<int> size;
  int root;
  treap(T E, function<T(T, T)> f): E(E), f(f){
    N = 0;
    root = 0;
  }
  void eval(int v){
    size[v] = 1;
    if (left[v] != -1){
      size[v] += size[left[v]];
    }
    if (right[v] != -1){
      size[v] += size[right[v]];
    }
    prod[v] = node[v];
    if (left[v] != -1){
      prod[v] = f(prod[left[v]], prod[v]);
    }
    if (right[v] != -1){
      prod[v] = f(prod[v], prod[right[v]]);
    }
  }
  int right_rotate(int v){
    int w = left[v];
    left[v] = right[w];
    parent[w] = parent[v];
    if (right[w] != -1){
      parent[right[w]] = v;
    }
    right[w] = v;
    if (parent[w] != -1){
      if (left[parent[w]] == v){
        left[parent[w]] = w;
      } else {
        right[parent[w]] = w;
      }
    }
    parent[v] = w;
    if (root == v){
      root = w;
    }
    eval(v);
    return w;
  }
  int left_rotate(int v){
    int w = right[v];
    right[v] = left[w];
    parent[w] = parent[v];
    if (left[w] != -1){
      parent[left[w]] = v;
    }
    left[w] = v;
    if (parent[w] != -1){
      if (left[parent[w]] == v){
        left[parent[w]] = w;
      } else {
        right[parent[w]] = w;
      }
    }
    parent[v] = w;
    if (root == v){
      root = w;
    }
    eval(v);
    return w;
  }
  int get_id(int k){
    int v = root;
    while (true){
      int lsz = 0;
      if (left[v] != -1){
        lsz = size[left[v]];
      }
      if (k < lsz){
        v = left[v];
      } else if (k == lsz){
        return v;
      } else {
        k -= lsz + 1;
        v = right[v];
      }
    }
  }
  T operator [](int k){
    return node[get_id(k)];
  }
  void insert(int pos, T x, int pri){
    int v = -1;
    if (N > 0){
      v = root;
      while (true){
        int lsz = 0;
        if (left[v] != -1){
          lsz = size[left[v]];
        }
        if (pos <= lsz){
          if (left[v] == -1){
            left[v] = N;
            break;
          } else {
            v = left[v];
          }
        } else {
          pos -= lsz + 1;
          if (right[v] == -1){
            right[v] = N;
            break;
          } else {
            v = right[v];
          }
        }
      }
    }
    node.push_back(x);
    prod.push_back(x);
    priority.push_back(pri);
    parent.push_back(v);
    left.push_back(-1);
    right.push_back(-1);
    size.push_back(1);
    N++;
    if (N == 1){
      root = 0;
    }
    v = N - 1;
    while (parent[v] != -1){
      if (priority[parent[v]] < priority[v]){
        if (left[parent[v]] == v){
          v = right_rotate(parent[v]);
        } else {
          v = left_rotate(parent[v]);
        }
      } else {
        break;
      }
    }
    while (parent[v] != -1){
      eval(v);
      v = parent[v];
    }
    eval(v);
  }
  void erase(int k){
    int v = get_id(k);
    while (left[v] != -1 || right[v] != -1){
      if (left[v] != -1 && right[v] != -1){
        if (priority[left[v]] > priority[right[v]]){
          v = right[right_rotate(v)];
        } else {
          v = left[left_rotate(v)];
        }
      } else if (left[v] != -1){
        v = right[right_rotate(v)];
      } else {
        v = left[left_rotate(v)];
      }
    }
    int w = v;
    size[w] = 0;
    prod[w] = E;
    while (parent[w] != -1){
      w = parent[w];
      eval(w);
    }
    if (parent[v] != -1){
      if (left[parent[v]] == v){
        left[parent[v]] = -1;
      } else {
        right[parent[v]] = -1;
      }
    }
    if (v != N - 1){
      if (parent[N - 1] != -1){
        if (left[parent[N - 1]] == N - 1){
          left[parent[N - 1]] = v;
        } else {
          right[parent[N - 1]] = v;
        }
      }
      if (left[N - 1] != -1){
        parent[left[N - 1]] = v;
      }
      if (right[N - 1] != -1){
        parent[right[N - 1]] = v;
      }
      node[v] = node[N - 1];
      prod[v] = prod[N - 1];
      priority[v] = priority[N - 1];
      parent[v] = parent[N - 1];
      left[v] = left[N - 1];
      right[v] = right[N - 1];
      size[v] = size[N - 1];
      if (root == N - 1){
        root = v;
      }
    }
    node.pop_back();
    prod.pop_back();
    priority.pop_back();
    parent.pop_back();
    left.pop_back();
    right.pop_back();
    size.pop_back();
    N--;
  }
  void update(int k, T x){
    int v = get_id(k);
    node[v] = x;
    while (parent[v] != -1){
      eval(v);
      v = parent[v];
    }
    eval(v);
  }
  T range_fold(int L, int R, int i, int l, int r){
    if (r <= L || R <= l){
      return E;
    } else if (L <= l && r <= R){
      return prod[i];
    } else {
      int lsz = 0;
      if (left[i] != -1){
        lsz = size[left[i]];
      }
      T ans = E;
      if (L <= l + lsz && l + lsz < R){
        ans = node[i];
      }
      if (left[i] != -1){
        ans = f(range_fold(L, R, left[i], l, l + lsz), ans);
      }
      if (right[i] != -1){
        ans = f(ans, range_fold(L, R, right[i], l + lsz + 1, r));
      }
      return ans;
    }
  }
  T range_fold(int L, int R){
    return range_fold(L, R, root, 0, N);
  }
};
#line 1 "old_Data_Structures/Treap.cpp"
template <typename T>
struct treap{
  int N;
  T E;
  function<T(T, T)> f;
  vector<T> node;
  vector<T> prod;
  vector<int> priority;
  vector<int> parent;
  vector<int> left, right;
  vector<int> size;
  int root;
  treap(T E, function<T(T, T)> f): E(E), f(f){
    N = 0;
    root = 0;
  }
  void eval(int v){
    size[v] = 1;
    if (left[v] != -1){
      size[v] += size[left[v]];
    }
    if (right[v] != -1){
      size[v] += size[right[v]];
    }
    prod[v] = node[v];
    if (left[v] != -1){
      prod[v] = f(prod[left[v]], prod[v]);
    }
    if (right[v] != -1){
      prod[v] = f(prod[v], prod[right[v]]);
    }
  }
  int right_rotate(int v){
    int w = left[v];
    left[v] = right[w];
    parent[w] = parent[v];
    if (right[w] != -1){
      parent[right[w]] = v;
    }
    right[w] = v;
    if (parent[w] != -1){
      if (left[parent[w]] == v){
        left[parent[w]] = w;
      } else {
        right[parent[w]] = w;
      }
    }
    parent[v] = w;
    if (root == v){
      root = w;
    }
    eval(v);
    return w;
  }
  int left_rotate(int v){
    int w = right[v];
    right[v] = left[w];
    parent[w] = parent[v];
    if (left[w] != -1){
      parent[left[w]] = v;
    }
    left[w] = v;
    if (parent[w] != -1){
      if (left[parent[w]] == v){
        left[parent[w]] = w;
      } else {
        right[parent[w]] = w;
      }
    }
    parent[v] = w;
    if (root == v){
      root = w;
    }
    eval(v);
    return w;
  }
  int get_id(int k){
    int v = root;
    while (true){
      int lsz = 0;
      if (left[v] != -1){
        lsz = size[left[v]];
      }
      if (k < lsz){
        v = left[v];
      } else if (k == lsz){
        return v;
      } else {
        k -= lsz + 1;
        v = right[v];
      }
    }
  }
  T operator [](int k){
    return node[get_id(k)];
  }
  void insert(int pos, T x, int pri){
    int v = -1;
    if (N > 0){
      v = root;
      while (true){
        int lsz = 0;
        if (left[v] != -1){
          lsz = size[left[v]];
        }
        if (pos <= lsz){
          if (left[v] == -1){
            left[v] = N;
            break;
          } else {
            v = left[v];
          }
        } else {
          pos -= lsz + 1;
          if (right[v] == -1){
            right[v] = N;
            break;
          } else {
            v = right[v];
          }
        }
      }
    }
    node.push_back(x);
    prod.push_back(x);
    priority.push_back(pri);
    parent.push_back(v);
    left.push_back(-1);
    right.push_back(-1);
    size.push_back(1);
    N++;
    if (N == 1){
      root = 0;
    }
    v = N - 1;
    while (parent[v] != -1){
      if (priority[parent[v]] < priority[v]){
        if (left[parent[v]] == v){
          v = right_rotate(parent[v]);
        } else {
          v = left_rotate(parent[v]);
        }
      } else {
        break;
      }
    }
    while (parent[v] != -1){
      eval(v);
      v = parent[v];
    }
    eval(v);
  }
  void erase(int k){
    int v = get_id(k);
    while (left[v] != -1 || right[v] != -1){
      if (left[v] != -1 && right[v] != -1){
        if (priority[left[v]] > priority[right[v]]){
          v = right[right_rotate(v)];
        } else {
          v = left[left_rotate(v)];
        }
      } else if (left[v] != -1){
        v = right[right_rotate(v)];
      } else {
        v = left[left_rotate(v)];
      }
    }
    int w = v;
    size[w] = 0;
    prod[w] = E;
    while (parent[w] != -1){
      w = parent[w];
      eval(w);
    }
    if (parent[v] != -1){
      if (left[parent[v]] == v){
        left[parent[v]] = -1;
      } else {
        right[parent[v]] = -1;
      }
    }
    if (v != N - 1){
      if (parent[N - 1] != -1){
        if (left[parent[N - 1]] == N - 1){
          left[parent[N - 1]] = v;
        } else {
          right[parent[N - 1]] = v;
        }
      }
      if (left[N - 1] != -1){
        parent[left[N - 1]] = v;
      }
      if (right[N - 1] != -1){
        parent[right[N - 1]] = v;
      }
      node[v] = node[N - 1];
      prod[v] = prod[N - 1];
      priority[v] = priority[N - 1];
      parent[v] = parent[N - 1];
      left[v] = left[N - 1];
      right[v] = right[N - 1];
      size[v] = size[N - 1];
      if (root == N - 1){
        root = v;
      }
    }
    node.pop_back();
    prod.pop_back();
    priority.pop_back();
    parent.pop_back();
    left.pop_back();
    right.pop_back();
    size.pop_back();
    N--;
  }
  void update(int k, T x){
    int v = get_id(k);
    node[v] = x;
    while (parent[v] != -1){
      eval(v);
      v = parent[v];
    }
    eval(v);
  }
  T range_fold(int L, int R, int i, int l, int r){
    if (r <= L || R <= l){
      return E;
    } else if (L <= l && r <= R){
      return prod[i];
    } else {
      int lsz = 0;
      if (left[i] != -1){
        lsz = size[left[i]];
      }
      T ans = E;
      if (L <= l + lsz && l + lsz < R){
        ans = node[i];
      }
      if (left[i] != -1){
        ans = f(range_fold(L, R, left[i], l, l + lsz), ans);
      }
      if (right[i] != -1){
        ans = f(ans, range_fold(L, R, right[i], l + lsz + 1, r));
      }
      return ans;
    }
  }
  T range_fold(int L, int R){
    return range_fold(L, R, root, 0, N);
  }
};
Back to top page