Problem p02698 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define PI acos(-1)
#define vi vector<int>
#define pi pair<int, int>
#define pl pair<ll, ll>
template <class T> istream &operator>>(istream &is, vector<T> &v) {
  for (auto &elemnt : v)
    is >> elemnt;
  return is;
}
template <class T, class U> istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}
const int MOD = 1e9 + 7;
const int INF = numeric_limits<int>::max() - (int)1e8;
const ll INFLL = numeric_limits<ll>::max() - (ll)1e17;

template <typename T> struct edge {
  pair<size_t, size_t> arrow;
  T cost;

  edge(size_t source, size_t to, T cost) : arrow(source, to), cost(cost) {}
  edge(size_t to, T cost) : arrow(-1, to), cost(cost) {}

  edge &operator=(const size_t &vertex) {
    arrow.second = vertex;
    return *this;
  }

  operator size_t() const { return arrow.second; }
};

template <typename T> struct UnWeightedGraph {
  vector<vector<edge<T>>> data;
  bool is_directed_graph;

  explicit UnWeightedGraph(size_t size, bool is_directed_graph)
      : data(size), is_directed_graph(is_directed_graph) {}

  void add_edge(size_t source, size_t to) {
    data[source].emplace_back(to, 0);
    if (!is_directed_graph)
      data[to].emplace_back(source, 0);
  }

  vector<edge<T>> &operator[](const size_t index) { return data[index]; }

  const size_t size() const { return data.size(); }
};

template <typename T> struct WeightedGraph : UnWeightedGraph<T> {
  explicit WeightedGraph(size_t size, bool is_directed_graph)
      : UnWeightedGraph<T>(size, is_directed_graph) {}

  void add_edge(size_t source, size_t to, T cost) {
    UnWeightedGraph<T>::operator[](source).emplace_back(to, cost);
    if (!UnWeightedGraph<T>::is_directed_graph)
      UnWeightedGraph<T>::operator[](to).emplace_back(source, cost);
  }
};

template <typename T> class EulerTour {
private:
  UnWeightedGraph<T> &graph;
  vector<size_t> euler_data, euler_in, euler_out;
  size_t data_size;

  void dfs(size_t now_vertex, size_t before_vertex, size_t &reference_count) {
    euler_in[now_vertex] = reference_count;
    euler_data[reference_count++] = now_vertex;
    for (auto next_vertex : graph[now_vertex]) {
      if (reference_count != 0 && next_vertex == before_vertex)
        continue;
      dfs(next_vertex, now_vertex, reference_count);
      euler_data[reference_count++] = now_vertex;
    }
    euler_out[now_vertex] = reference_count;
  }

public:
  explicit EulerTour(UnWeightedGraph<T> &graph)
      : graph(graph), euler_data(2 * graph.size()), euler_in(graph.size()),
        euler_out(graph.size()), data_size(0) {}

  void build(size_t start_vertex = 0) {
    size_t reference_count = 0;
    dfs(start_vertex, 0, reference_count);
    data_size = reference_count;
  }

  // [left, right) = [first, second)
  pair<int, int> index_of_vertex(const int vertex) {
    return {euler_in[vertex], euler_out[vertex]};
  }

  int pre_oreder(const int vertex) { return euler_in[vertex]; }

  // When using it in a query, the closed-interval.
  int post_order(const int vertex) { return euler_out[vertex] - 1; }

  // read only
  const size_t &operator[](const size_t index) const {
    return euler_data[index];
  }

  size_t size() const noexcept { return data_size; }
};

template <typename T> class UndoableLongestIncreaseingSubsequence {
private:
  struct operation_infomation {
    bool is_insert;
    T before, after;

    operation_infomation(bool is_insert, T before, T after)
        : is_insert(is_insert), before(before), after(after) {}
  };

  multiset<T> lis_data;
  list<operation_infomation> update_infomation;
  bool is_narrowly_sense;

public:
  explicit UndoableLongestIncreaseingSubsequence(bool is_narrowly_sense)
      : is_narrowly_sense(is_narrowly_sense) {}

  size_t update(T add) {
    typename multiset<T>::iterator iter;
    if (is_narrowly_sense)
      iter = lis_data.lower_bound(add);
    else
      iter = lis_data.upper_bound(add);
    if (iter == lis_data.end()) {
      lis_data.insert(add);
      update_infomation.emplace_back(true, add, add);
    } else {
      update_infomation.emplace_back(false, *iter, add);
      lis_data.erase(iter);
      lis_data.insert(add);
    }
    return lis_data.size();
  }

  void undo() {
    if (lis_data.empty())
      return;
    operation_infomation operation = update_infomation.back();
    auto iter = lis_data.lower_bound(operation.after);
    lis_data.erase(iter);
    if (!operation.is_insert)
      lis_data.insert(operation.before);
    update_infomation.erase(next(update_infomation.end(), -1));
  }
};

template <typename T> class LongestIncreaseingSubsequenceTree {
private:
  UnWeightedGraph<T> tree;
  EulerTour<T> euler_tour;
  vector<T> vertex_number_data;
  vector<size_t> vertex_lis_size;
  UndoableLongestIncreaseingSubsequence<T> count_lis;

  void dfs() {
    for (size_t index = 0; index < euler_tour.size(); index++) {
      size_t now_vertex = euler_tour[index];
      size_t pre_order, post_order;
      tie(pre_order, post_order) = euler_tour.index_of_vertex(now_vertex);
      post_order--;
      if (pre_order == index) {
        vertex_lis_size[now_vertex] =
            count_lis.update(vertex_number_data[now_vertex]);
      }
      if (post_order == index) {
        count_lis.undo();
      }
    }
  }

public:
  explicit LongestIncreaseingSubsequenceTree(size_t vertex_size,
                                             bool is_narrowly_sense)
      : tree(vertex_size, false), euler_tour(tree),
        vertex_number_data(vertex_size, 0), vertex_lis_size(vertex_size),
        count_lis(is_narrowly_sense) {}

  void add_edge(size_t source, size_t to) { tree.add_edge(source, to); }

  void init_vertex(size_t vertex, T number) {
    vertex_number_data[vertex] = number;
  }

  void build(size_t start_vertex = 0) {
    euler_tour.build(start_vertex);
    dfs();
  }

  const size_t &operator[](size_t vertex) { return vertex_lis_size[vertex]; }
};

int main() {
  int N;
  cin >> N;
  LongestIncreaseingSubsequenceTree<int> tree(N, true);
  for (int i = 0; i < N; i++) {
    int a;
    cin >> a;
    tree.init_vertex(i, a);
  }
  for (int i = 0; i < N - 1; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    tree.add_edge(u, v);
  }
  tree.build();
  for (int i = 0; i < N; i++) {
    cout << tree[i] << endl;
  }
}

Error: WA

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define PI acos(-1)
#define vi vector<int>
#define pi pair<int, int>
#define pl pair<ll, ll>
template <class T> istream &operator>>(istream &is, vector<T> &v) {
  for (auto &elemnt : v)
    is >> elemnt;
  return is;
}
template <class T, class U> istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}
const int MOD = 1e9 + 7;
const int INF = numeric_limits<int>::max() - (int)1e8;
const ll INFLL = numeric_limits<ll>::max() - (ll)1e17;

#include <bits/stdc++.h>
using namespace std;

// Last updated 2020-4-30
template <typename T> struct edge {
  pair<int, int> arrow;
  T cost;

  edge(int source, int to, T cost) : arrow(source, to), cost(cost) {}
  edge(int to, T cost) : arrow(-1, to), cost(cost) {}

  edge &operator=(const int &vertex) {
    arrow.second = vertex;
    return *this;
  }

  operator int() const { return arrow.second; }
};

template <typename T> struct UnWeightedGraph {
  vector<vector<edge<T>>> data;
  bool is_directed_graph;
  explicit UnWeightedGraph(size_t size, bool is_directed_graph)
      : data(size), is_directed_graph(is_directed_graph) {}

  void add_edge(int source, int to) {
    data[source].emplace_back(to, 0);
    if (!is_directed_graph)
      data[to].emplace_back(source, 0);
  }

  vector<edge<T>> &operator[](const size_t index) { return data[index]; }

  const size_t size() const { return data.size(); }
};

template <typename T> struct WeightedGraph : UnWeightedGraph<T> {
  explicit WeightedGraph(size_t size, bool is_directed_graph)
      : UnWeightedGraph<T>(size, is_directed_graph) {}

  void add_edge(int source, int to, T cost) {
    UnWeightedGraph<T>::operator[](source).emplace_back(to, cost);
    if (!UnWeightedGraph<T>::is_directed_graph)
      UnWeightedGraph<T>::operator[](to).emplace_back(source, cost);
  }
};

// Last updated 2020-4-22
template <typename T> class EulerTour {
private:
  UnWeightedGraph<T> &graph;
  vector<int> euler_data, euler_in, euler_out;
  size_t data_size;

  void dfs(int now_vertex, int before_vertex, int &reference_count) {
    euler_in[now_vertex] = reference_count;
    euler_data[reference_count++] = now_vertex;
    for (auto next_vertex : graph[now_vertex]) {
      if (next_vertex == before_vertex)
        continue;
      dfs(next_vertex, now_vertex, reference_count);
      euler_data[reference_count++] = now_vertex;
    }
    euler_out[now_vertex] = reference_count;
  }

public:
  explicit EulerTour(UnWeightedGraph<T> &graph, size_t data_size)
      : graph(graph), euler_data(2 * data_size), euler_in(data_size),
        euler_out(data_size), data_size(0) {}

  void build(int start_vertex = 0) {
    int reference_count = 0;
    dfs(start_vertex, -1, reference_count);
    data_size = reference_count;
  }

  // [left, right) = [first, second)
  pair<int, int> index_of_vertex(const int vertex) {
    return {euler_in[vertex], euler_out[vertex]};
  }

  int pre_oreder(const int vertex) { return euler_in[vertex]; }

  // When using it in a query, the closed-interval.
  int post_order(const int vertex) { return euler_out[vertex] - 1; }

  // read only
  const int &operator[](const int index) const { return euler_data[index]; }

  size_t size() const noexcept { return data_size; }
};

// Last updated 2020-4-22
template <typename T> class BinaryIndexedTree {
private:
  vector<T> data;

public:
  explicit BinaryIndexedTree(size_t data_size) : data(data_size + 1, 0) {}

  void update(size_t index, T value) {
    for (size_t now_index = index + 1; now_index < data.size();
         now_index += (now_index & -now_index)) {
      data[now_index] += value;
    }
  }

  T sum(size_t index) {
    T count_up = 0;
    for (size_t now_index = index + 1; now_index > 0;
         now_index -= (now_index & -now_index)) {
      count_up += data[now_index];
    }
    return count_up;
  }

  T sum_all() { return sum(data.size() - 1); }

  // [left, right)
  T query(int left_index, int right_index) {
    return sum(right_index - 1) - sum(left_index - 1);
  }
};

// Last updated 2020-4-27
template <typename T, typename bit_type>
class CountUpEulerTour : public EulerTour<T> {
private:
  BinaryIndexedTree<bit_type> count_on_tree;
  size_t vertex_size;

  void reset_bit() {
    count_on_tree = BinaryIndexedTree<bit_type>(EulerTour<T>::size());
  }

  void vertex_update(size_t index, bit_type value, vector<bool> &is_already) {
    if (is_already[EulerTour<T>::operator[](index)])
      return;
    is_already[EulerTour<T>::operator[](index)] = true;
    count_on_tree.update(index, value);
  }

public:
  explicit CountUpEulerTour(UnWeightedGraph<T> &graph, size_t vertex_size)
      : EulerTour<T>(graph, vertex_size), count_on_tree(2 * vertex_size),
        vertex_size(vertex_size) {}

  void init_pre_order_count(bit_type base) {
    vector<bool> is_already_appeared(vertex_size, false);
    for (size_t index = 0; index < EulerTour<T>::size(); index++)
      vertex_update(index, base, is_already_appeared);
  }

  void init_post_order_count(bit_type base) {
    vector<bool> is_already_appeared(vertex_size, false);
    for (size_t index = EulerTour<T>::size() - 1; index >= 0; index--)
      vertex_update(index, base, is_already_appeared);
  }

  void reset_pre_order_count(bit_type base) {
    reset_bit();
    init_pre_order_count(base);
  }

  void reset_post_order_count(bit_type base) {
    reset_bit();
    init_post_order_count(base);
  }

  void reset_count() { reset_bit(); }

  void update(int partial_tree_root, bit_type value, bool check) {
    if (check)
      count_on_tree.update(
          EulerTour<T>::index_of_vertex(partial_tree_root).first, value);
    else
      count_on_tree.update(partial_tree_root, value);
  }

  bit_type query(pair<int, int> index) {
    return count_on_tree.query(index.first, index.second);
  }

  bit_type query(int partial_tree_root) {
    auto index = EulerTour<T>::index_of_vertex(partial_tree_root);
    return count_on_tree.query(index.first, index.second);
  }
};

int ans[300000];
int sub[300000];

template <typename T>
size_t longest_increasing_subsequence(const vector<T> &a, bool strict) {
  vector<T> lis;
  for (int i = 0; i < a.size(); i++) {
    auto &p = a[i];
    typename vector<T>::iterator it;
    if (strict)
      it = lower_bound(begin(lis), end(lis), p);
    else
      it = upper_bound(begin(lis), end(lis), p);
    if (end(lis) == it)
      lis.emplace_back(p);
    else
      *it = p;
    ans[i] = lis.size();
    if (i > 0) {
      if (ans[i] - ans[i - 1] == 1)
        sub[i] = 1;
    }
  }
  return lis.size();
}

int main() {
  int N;
  cin >> N;
  vector<int> a(N);
  cin >> a;
  UnWeightedGraph<int> tree(N, false);
  for (int i = 0; i < N - 1; i++) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    tree.add_edge(u, v);
  }
  CountUpEulerTour<int, int> euler(tree, N);
  euler.build();
  vector<int> check(2 * N, -1);
  for (int i = 0; i < N; i++) {
    check[euler.pre_oreder(i)] = a[i];
  }
  longest_increasing_subsequence(check, true);
  sub[0] = 1;
  bool INFCLK = false;
  for (int i = 0; i < 2 * N; i++) {
    if (sub[i] == 1) {
      euler.update(i, 1, false);
    }
  }
  cout << 1 << endl;
  for (int i = 1; i < N; i++) {
    int idx = euler.pre_oreder(i);
    int before = euler.pre_oreder(euler[idx - 1]) + 1;
    cout << euler.query({0, idx + 1}) - euler.query({before, idx}) << endl;
  }
}