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

#include <bits/stdc++.h>
#ifdef LOCAL_DEBUG
#define DEBUG 1
#define CERR                                                                   \\
  if (DEBUG)                                                                   \\
  cerr
#define MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, NAME, ...) NAME
#define pr(...)                                                                \\
  CERR << MACRO(__VA_ARGS__, pr10, pr9, pr8, pr7, pr6, pr5, pr4, pr3, pr2,     \\
                pr1)(__VA_ARGS__)                                              \\
       << endl
#define pr1(a) (#a) << "=" << (a) << " "
#define pr2(a, b) pr1(a) << pr1(b)
#define pr3(a, b, c) pr1(a) << pr2(b, c)
#define pr4(a, b, c, d) pr1(a) << pr3(b, c, d)
#define pr5(a, b, c, d, e) pr1(a) << pr4(b, c, d, e)
#define pr6(a, b, c, d, e, f) pr1(a) << pr5(b, c, d, e, f)
#define pr7(a, b, c, d, e, f, g) pr1(a) << pr6(b, c, d, e, f, g)
#define pr8(a, b, c, d, e, f, g, h) pr1(a) << pr7(b, c, d, e, f, g, h)
#define pr9(a, b, c, d, e, f, g, h, i) pr1(a) << pr8(b, c, d, e, f, g, h, i)
#define pr10(a, b, c, d, e, f, g, h, i, j)                                     \\
  pr1(a) << pr9(b, c, d, e, f, g, h, i, j)
#define prArr(a)                                                               \\
  {                                                                            \\
    CERR << (#a) << "={";                                                      \\
    int i = 0;                                                                 \\
    for (auto t : (a))                                                         \\
      CERR << (i++ ? ", " : "") << t;                                          \\
    CERR << "}" << endl;                                                       \\
  }
#else
#define DEBUG 0
#define pr(...)
#define prArr(a)
#endif
using namespace std;
using Int = long long;
using _int = int;
using ll = long long;
using Double = long double;
const Int INF = (1LL << 60) + 1e9; // ~ 1.15 * 1e18
const Int mod = (1e9) + 7;
const Double EPS = 1e-8;
const Double PI = 6.0 * asin((Double)0.5);
using P = pair<Int, Int>;
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }
template <class T1, class T2> ostream &operator<<(ostream &o, pair<T1, T2> p) {
  return o << "(" << p.first << "," << p.second << ")";
}
template <class T1, class T2, class T3>
ostream &operator<<(ostream &o, tuple<T1, T2, T3> t) {
  return o << "(" << get<0>(t) << "," << get<1>(t) << "," << get<2>(t) << ")";
}
template <class T1, class T2> istream &operator>>(istream &i, pair<T1, T2> &p) {
  return i >> p.first >> p.second;
}
template <class T> ostream &operator<<(ostream &o, vector<T> a) {
  Int i = 0;
  for (T t : a)
    o << (i++ ? " " : "") << t;
  return o;
}
template <class T> istream &operator>>(istream &i, vector<T> &a) {
  for (T &t : a)
    i >> t;
  return i;
}
// INSERT ABOVE HERE

template <typename T> class Compress {
public:
  vector<T> X;
  bool ok;
  Compress() : ok(false){};

  Int size() {
    assert(ok);
    return X.size();
  }
  // void add(T a){ok = false; X.push_back(a); X.push_back(a-1);
  // X.push_back(a+1);}
  void add(T a) {
    ok = false;
    X.push_back(a);
  };
  void add(const vector<T> a) {
    for (T x : a)
      add(x);
  }
  // void add(const vector<T> &a){for(T x:a) add(x);}

  void build() {
    ok = true;
    sort(X.begin(), X.end());
    X.erase(unique(X.begin(), X.end()), X.end());
  }

  Int getL(T x) {
    assert(ok);
    return lower_bound(X.begin(), X.end(), x) - X.begin();
  }
  Int getU(T x) {
    assert(ok);
    return upper_bound(X.begin(), X.end(), x) - X.begin();
  }
};

template <typename dtype, dtype initValue /*範囲外のときに返す値*/> class RMQ {
public:
  Int n, n_;
  vector<dtype> dat;
  Int toMax;

  // 初期化
  RMQ() { n = -1; }
  RMQ(Int n_, Int toMax = 0) : n_(n_), toMax(toMax) {
    n = 1;
    while (n < n_)
      n *= 2;
    dat.resize(2 * n - 1, initValue);
  }

  inline dtype merge(dtype a, dtype b) { return toMax ? max(a, b) : min(a, b); }

  // k番目の値をaに変更
  void update(Int k, dtype a) {
    k += n - 1;
    dat[k] = a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = merge(dat[k * 2 + 1], dat[k * 2 + 2]);
    }
  }

  dtype dfs(Int a, Int b, Int k, Int l, Int r) {
    if (r <= a || b <= l)
      return initValue;
    if (a <= l && r <= b)
      return dat[k];
    dtype vl = dfs(a, b, k * 2 + 1, l, (l + r) / 2);
    dtype vr = dfs(a, b, k * 2 + 2, (l + r) / 2, r);
    return merge(vl, vr);
  }

  //[a,b)の最小値を求める
  dtype get(Int a, Int b) {
    assert(a <= b), assert(a <= n_ && b <= n_), assert(a >= 0 && a >= 0);
    return dfs(a, b, 0, 0, n);
  }
};

Int N;
vector<Int> A;
vector<vector<Int>> G;
vector<Int> ans;
RMQ<Int, 0> rmq;
Compress<Int> cmp;

void dfs(Int pos, Int pre) {
  Int num = cmp.getL(A[pos]);
  Int score = rmq.get(0, num) + 1;
  Int tmp = rmq.get(num, num + 1);
  if (tmp < score)
    rmq.update(num, score);
  ans[pos] = rmq.get(0, cmp.size());

  for (Int to : G[pos]) {
    if (to == pre)
      continue;
    dfs(to, pos);
  }
  rmq.update(num, tmp);
}

signed main() {
  srand((unsigned)time(NULL));
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  cin >> N;
  A.resize(N);
  G.resize(N);
  cin >> A;
  for (Int i = 0; i < N - 1; i++) {
    Int a, b;
    cin >> a >> b;
    a--, b--;
    G[a].push_back(b);
    G[b].push_back(a);
  }

  cmp.add(A);
  cmp.build();
  ans.resize(N);
  rmq = RMQ<Int, 0>(cmp.size(), 1);
  rmq.update(0, 0);
  dfs(0, -1);
  for (Int a : ans)
    cout << a << endl;

  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
#ifdef LOCAL_DEBUG
#define DEBUG 1
#define CERR                                                                   \\
  if (DEBUG)                                                                   \\
  cerr
#define MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, NAME, ...) NAME
#define pr(...)                                                                \\
  CERR << MACRO(__VA_ARGS__, pr10, pr9, pr8, pr7, pr6, pr5, pr4, pr3, pr2,     \\
                pr1)(__VA_ARGS__)                                              \\
       << endl
#define pr1(a) (#a) << "=" << (a) << " "
#define pr2(a, b) pr1(a) << pr1(b)
#define pr3(a, b, c) pr1(a) << pr2(b, c)
#define pr4(a, b, c, d) pr1(a) << pr3(b, c, d)
#define pr5(a, b, c, d, e) pr1(a) << pr4(b, c, d, e)
#define pr6(a, b, c, d, e, f) pr1(a) << pr5(b, c, d, e, f)
#define pr7(a, b, c, d, e, f, g) pr1(a) << pr6(b, c, d, e, f, g)
#define pr8(a, b, c, d, e, f, g, h) pr1(a) << pr7(b, c, d, e, f, g, h)
#define pr9(a, b, c, d, e, f, g, h, i) pr1(a) << pr8(b, c, d, e, f, g, h, i)
#define pr10(a, b, c, d, e, f, g, h, i, j)                                     \\
  pr1(a) << pr9(b, c, d, e, f, g, h, i, j)
#define prArr(a)                                                               \\
  {                                                                            \\
    CERR << (#a) << "={";                                                      \\
    int i = 0;                                                                 \\
    for (auto t : (a))                                                         \\
      CERR << (i++ ? ", " : "") << t;                                          \\
    CERR << "}" << endl;                                                       \\
  }
#else
#define DEBUG 0
#define pr(...)
#define prArr(a)
#endif
using namespace std;
using Int = long long;
using _int = int;
using ll = long long;
using Double = long double;
const Int INF = (1LL << 60) + 1e9; // ~ 1.15 * 1e18
const Int mod = (1e9) + 7;
const Double EPS = 1e-8;
const Double PI = 6.0 * asin((Double)0.5);
using P = pair<Int, Int>;
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }
template <class T1, class T2> ostream &operator<<(ostream &o, pair<T1, T2> p) {
  return o << "(" << p.first << "," << p.second << ")";
}
template <class T1, class T2, class T3>
ostream &operator<<(ostream &o, tuple<T1, T2, T3> t) {
  return o << "(" << get<0>(t) << "," << get<1>(t) << "," << get<2>(t) << ")";
}
template <class T1, class T2> istream &operator>>(istream &i, pair<T1, T2> &p) {
  return i >> p.first >> p.second;
}
template <class T> ostream &operator<<(ostream &o, vector<T> a) {
  Int i = 0;
  for (T t : a)
    o << (i++ ? " " : "") << t;
  return o;
}
template <class T> istream &operator>>(istream &i, vector<T> &a) {
  for (T &t : a)
    i >> t;
  return i;
}
// INSERT ABOVE HERE

template <typename T> class Compress {
public:
  vector<T> X;
  bool ok;
  Compress() : ok(false){};

  Int size() {
    assert(ok);
    return X.size();
  }
  void add(T a) {
    ok = false;
    X.push_back(a);
    X.push_back(a - 1);
    X.push_back(a + 1);
  }
  void add(const vector<T> a) {
    for (T x : a)
      add(x);
  }
  // void add(const vector<T> &a){for(T x:a) add(x);}

  void build() {
    ok = true;
    sort(X.begin(), X.end());
    X.erase(unique(X.begin(), X.end()), X.end());
  }

  Int getL(T x) {
    assert(ok);
    return lower_bound(X.begin(), X.end(), x) - X.begin();
  }
  Int getU(T x) {
    assert(ok);
    return upper_bound(X.begin(), X.end(), x) - X.begin();
  }
};

template <typename D, Int toMaxQuery, Int useAssert = 1> class RMQ {
public:
  struct T {  // 遅延データ
    Int type; // 0 - empty, 1 - update, 2 - ifUpdate
    D value;
    T() : type(0) {}
    T(Int type, D value) : type(type), value(value) {}
  };

  Int n, n_;
  D initD;   // datの初期値
  D returnD; // 範囲外の時に返す値
  vector<D> dat;
  vector<T> td;

  RMQ() { n = -1; }
  RMQ(Int n_, D initD) : n_(n_), initD(initD), returnD(initD) {
    n = 1;
    while (n < n_)
      n *= 2;
    td.resize(2 * n - 1, T());
    dat.resize(2 * n - 1, initD);
  }

  // 目的データのマージ
  inline D mergeD(D l, D r) { return toMaxQuery ? max(l, r) : min(l, r); }

  // 遅延データのマージ
  inline T mergeT(const T &from, const T &to) {
    if (to.type == 0)
      return from;
    if (from.type == 0)
      return to; // from-empty
    if (to.type == 1)
      return to; // to-update;
    if (to.type == 2)
      return T(from.type, mergeD(from.value, to.value)); // to-ifupdate
    if (useAssert)
      assert(0);
    return T();
  }

  // 目的データに遅延データを反映
  inline void apply(D &a, const T &b) {
    if (b.type == 0)
      return;
    if (b.type == 1)
      a = b.value; // update
    else
      a = mergeD(a, b.value); // if-update
  }

  D dfs(Int a, Int b, const T x, Int k, Int l, Int r) {
    if (r <= a || b <= l)
      return x.type == 0 ? returnD : dat[k];
    if (a <= l && r <= b) {
      td[k] = mergeT(td[k], x);
      apply(dat[k], x);
      return dat[k];
    }
    Int kl = k * 2 + 1, kr = k * 2 + 2;
    { // 遅延を子に反映
      td[kl] = mergeT(td[kl], td[k]);
      td[kr] = mergeT(td[kr], td[k]);
      apply(dat[kl], td[k]);
      apply(dat[kr], td[k]);
      td[k] = T();
    }
    D vl = dfs(a, b, x, kl, l, (l + r) / 2);
    D vr = dfs(a, b, x, kr, (l + r) / 2, r);
    return x.type == 0 ? mergeD(vl, vr) : (dat[k] = mergeD(vl, vr));
  }

  //[l,r)の値をxに変更　update(l,r,x)
  void update(Int l, Int r, D x) {
    if (useAssert)
      assert(l <= r), assert(l <= n && r <= n), assert(l >= 0 && r >= 0);
    dfs(l, r, T(1, x), 0, 0, n);
  }

  //[l,r)の値をもしもxの方が小さければ変更　ifupdate(l,r,x)
  // toMaxのときは[l,r)の値をもしもxの方が大きければ変更　ifupdate(l,r,x)
  void ifupdate(Int l, Int r, D x) {
    if (useAssert)
      assert(l <= r), assert(l <= n && r <= n), assert(l >= 0 && r >= 0);
    dfs(l, r, T(2, x), 0, 0, n);
  }

  //[l,r)の最小値を得る　get(l,r);
  D get(Int l, Int r) {
    if (useAssert)
      assert(l <= r), assert(l <= n && r <= n), assert(l >= 0 && r >= 0);
    return dfs(l, r, T(0, initD), 0, 0, n);
  }
};

Int N;
vector<Int> A;
vector<vector<Int>> G;
vector<Int> ans;
RMQ<Int, 1, 1> rmq;
Compress<Int> cmp;

void dfs(Int pos, Int pre) {

  Int num = cmp.getL(A[pos]);
  Int score = rmq.get(0, num) + 1;
  rmq.ifupdate(num, num + 1, score);
  ans[pos] = score;

  for (Int to : G[pos]) {
    if (to == pre)
      continue;
    dfs(to, pos);
  }
  rmq.update(num, num + 1, score - 1);
}

signed main() {
  srand((unsigned)time(NULL));
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  cin >> N;
  A.resize(N);
  G.resize(N);
  cin >> A;
  for (Int i = 0; i < N - 1; i++) {
    Int a, b;
    cin >> a >> b;
    a--, b--;
    G[a].push_back(b);
    G[b].push_back(a);
  }

  rmq = RMQ<Int, 1, 1>(N, -INF);
  rmq.update(0, 1, 0);
  cmp.add(A);
  cmp.build();
  ans.resize(N);
  dfs(0, -1);
  for (Int a : ans)
    cout << a << endl;

  return 0;
}