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

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>

using namespace std;

#define LL long long

const int dx[4] = {1, -1, 0, 0};
const int dy[4] = {0, 0, 1, -1};

LL mod(LL x, LL md) { return ((x % md) + md) % md; }

class Mint {
public:
  static LL md;
  LL x;
  Mint(LL _x) { x = mod(_x, md); }
  Mint(const Mint &y) { x = mod(y.x, md); }
};

void MintMyExgcd(LL a, LL b, LL &x, LL &y) {
  // solve equation ax + by = 1 (mod m)
  LL md = Mint::md;
  if (b == 0) {
    y = 0;
    x = 1;
    return;
  }
  MintMyExgcd(b, a % b, x, y);
  LL t = y;
  y = mod(x - (a / b) * y, md);
  x = t;
}

LL MintNY(LL x) {
  if (x == 0) {
    return 1;
  }
  LL md = Mint::md;
  LL a, b;
  MintMyExgcd(x, md, a, b);
  while (a < 0) {
    a += md;
  }
  return a;
}

/* LL gcd(LL a, LL b) {
        if (b == 0) {
                return a;
        }
        return gcd(b, a % b);
} */

Mint operator+(Mint a, Mint b) { return Mint(mod(a.x + b.x, Mint::md)); }
Mint operator-(Mint a, Mint b) { return Mint(mod(a.x - b.x, Mint::md)); }
Mint operator*(Mint a, Mint b) { return Mint(mod(a.x * b.x, Mint::md)); }
Mint operator/(Mint a, Mint b) {
  Mint c = Mint(MintNY(b.x));
  return Mint(mod(a.x * c.x, Mint::md));
}

Mint operator-(Mint a) { return Mint(-a.x); }
bool operator==(Mint a, Mint b) { return a.x == b.x; }
bool operator!=(Mint a, Mint b) { return a.x != b.x; }
bool operator>(Mint a, Mint b) { return a.x > b.x; }
bool operator<(Mint a, Mint b) { return a.x < b.x; }
bool operator>=(Mint a, Mint b) { return a.x >= b.x; }
bool operator<=(Mint a, Mint b) { return a.x <= b.x; }

void operator+=(Mint &a, Mint b) { a = a + b; }
void operator-=(Mint &a, Mint b) { a = a - b; }
void operator*=(Mint &a, Mint b) { a = a * b; }
void operator/=(Mint &a, Mint b) { a = a / b; }

ostream &operator<<(ostream &out, Mint a) {
  out << a.x;
  return out;
}

istream &operator>>(istream &in, Mint &a) {
  in >> a.x;
  return in;
}

Mint factorial(LL n) {
  if (n == 0) {
    return Mint(1);
  }
  Mint res = 1;
  for (LL i = 1; i <= n; ++i) {
    res *= i;
  }
  return res;
}
Mint multiRange(LL s, LL t) {
  Mint res = 1;
  for (LL i = s; i <= t; ++i) {
    res *= i;
  }
  return res;
}

Mint getC(LL n, LL k) {
  if (n - k < k) {
    return getC(n, n - k);
  }
  return multiRange(n - k + 1, n) / factorial(k);
}

Mint getA(LL n, LL k) { return multiRange(n - k + 1, n); }

Mint countNonNegativeDivision(LL n, LL k) { return getC(n + k - 1, k - 1); }
Mint countPositiveDivision(LL n, LL k) {
  if (n < k) {
    return 0;
  }
  if (k <= 0) {
    return 0;
  }
  return getC(n - 1, k - 1);
}
Mint quickMod(Mint a, LL b) {
  Mint res = 1;
  while (b > 0) {
    if (b % 2) {
      res *= a;
    }
    a *= a;
    b /= 2;
  }
  return res;
}

LL Mint::md = 1000000007;

class Edge {
public:
  int t, nxt;
  bool isDir;
  Edge(int _t, int _nxt, bool _isDir = false)
      : t(_t), nxt(_nxt), isDir(_isDir) {}
};
class Node {
public:
  Node *left, *right;
  int res;
  Node(int _res) : res(_res) { left = right = NULL; }
};

class ChairManTree {
public:
  int n;
  vector<Node *> v;
  int cur;
  Node *buildTree(int l, int r) {
    // cout << "build " << endl;
    if (l == r) {
      return new Node(0);
    }
    Node *nd = new Node(0);
    int mid = (l + r) / 2;
    nd->left = buildTree(l, mid);
    nd->right = buildTree(mid + 1, r);
    return nd;
  }
  ChairManTree(int _n) : n(_n) {
    v.clear();
    v.push_back(buildTree(0, n - 1));
    cur = 0;
  }
  void push(int x, int val) {
    // printf("push(%d, %d)\\n", x, val);
    Node *oldR = v[cur];
    Node *newR = new Node(max(v[cur]->res, val));
    Node *rt = newR;
    int l = 0, r = n - 1;
    while (l < r) {
      // cout << "l = " << l << ", r = " << r << endl;
      int mid = (l + r) / 2;
      if (x > mid) {
        newR->left = oldR->left;
        newR->right = new Node(max(oldR->right->res, val));
        newR = newR->right;
        oldR = oldR->right;
        l = mid + 1;
      } else {
        newR->right = oldR->right;
        newR->left = new Node(max(oldR->left->res, val));
        newR = newR->left;
        oldR = oldR->left;
        r = mid;
      }
    }
    v.push_back(rt);
    cur += 1;
  }
  int ask(Node *rr, int l, int r, int x) {
    // printf("ask(l = %d, r = %d, x = %d)\\n", l, r, x);
    if (r < x) {
      return rr->res;
    }
    if (l == r) {
      return 0;
    }
    int mid = (l + r) / 2;
    if (x > mid) {
      // cout << rr->left->res << endl;
      // cout << rr->right->res << endl;
      return max(rr->left->res, ask(rr->right, mid + 1, r, x));
    } else {
      // cout << rr->left->res << endl;
      return ask(rr->left, l, mid, x);
    }
  }
  int query(int x) {
    // printf("query(%d)\\n", x);
    Node *r = v[cur];
    return ask(r, 0, n - 1, x) + 1;
  }
  void pop() {
    // printf("pop()\\n");
    v.pop_back();
    cur -= 1;
  }
};

class Nums {
public:
  int idx, x;
  Nums(int _idx, int _x) : x(_x), idx(_idx) {}
};

bool cmp(const Nums &a, const Nums &b) { return a.x < b.x; }

vector<int> discretize(vector<int> &x, int &maxCur) {
  // cout << endl;
  vector<Nums> a;
  a.clear();
  for (int i = 0; i < x.size(); ++i) {
    a.push_back(Nums(i, x[i]));
  }
  sort(a.begin(), a.end(), cmp);
  int cur = 0;
  vector<int> res(a.size());
  for (int i = 0; i < a.size(); ++i) {
    // cout << a[i].idx << ' ' << a[i].x << endl;
    if (i != 0 && a[i].x != a[i - 1].x) {
      ++cur;
    }
    res[a[i].idx] = cur;
  }
  maxCur = cur;
  return res;
}

class Tree {
public:
  int n;
  vector<Edge> e;
  int edgeN;
  vector<int> h;
  vector<int> s, f;
  vector<int> c;
  vector<int> res;
  int root;
  vector<bool> vis;
  vector<int> a;
  ChairManTree *cmt;
  int maxCur;
  int ans;

  void addEdge(int u, int v) {
    // printf("addEdge(%d, %d)", u, v);
    e.push_back(Edge(v, h[u]));
    h[u] = edgeN++;
    e.push_back(Edge(u, h[v]));
    h[v] = edgeN++;
  }

  void initDFS(int r) {
    // cout << "dfs " << r << endl;
    s[r] = 1;
    vis[r] = true;
    for (int p = h[r]; p != -1; p = e[p].nxt) {
      int t = e[p].t;
      // printf("edge between (%d, %d)\\n", r, t);
      if (vis[t]) {
        e[p].isDir = false;
        continue;
      }
      e[p].isDir = true;
      f[t] = r;
      initDFS(t);
      s[r] += s[t];
    }
  }

  void initialize(int _root = 0) {
    root = _root;
    for (int i = 0; i < n; ++i) {
      s.push_back(0);
      f.push_back(-1);
      vis.push_back(false);
    }
    initDFS(root);
  }

  void printVector(vector<int> &x, string name) {
    cout << name << ": ";
    for (int i = 0; i < x.size(); ++i) {
      cout << x[i] << ' ';
    }
    cout << endl;
  }

  void checkOutput() {
    // printVector(s, "s");
    // printVector(f, "f");
    // printVector(h, "h");
    // cout << "root = " << root << endl;
  }

  Tree() {
    scanf("%d", &n);
    edgeN = 0;

    h.clear();
    for (int i = 0; i < n; ++i) {
      h.push_back(-1);
      c.push_back(0);
    }
    maxCur = 0;
    for (int i = 0; i < n; ++i) {
      scanf("%d", &c[i]);
      maxCur = max(maxCur, c[i]);
      // c[i] -= 1;
    }
    // cout << "load c" << endl;

    c = discretize(c, maxCur);
    // cout << "discretized" << endl;
    // for (int i = 0; i < c.size(); ++i) {
    // 	cout << c[i] << ' ';

    // }
    // cout << endl;

    int u, v;
    for (int i = 0; i < n - 1; ++i) {
      scanf("%d%d", &u, &v);
      addEdge(u - 1, v - 1);
    }
    // cout << "edges added" << endl;

    initialize();
    // checkOutput();
    // cout << "initialized" << endl;
    res = vector<int>(n + 1);
    cmt = new ChairManTree(maxCur + 1);
  }

  void workDFS(int r) {
    res[r] = cmt->query(c[r]);
    cmt->push(c[r], res[r]);

    int ansTmp = ans;
    ans = max(ans, res[r]);
    res[r] = ans;
    for (int p = h[r]; p != -1; p = e[p].nxt) {
      if (e[p].isDir) {
        workDFS(e[p].t);
      }
    }
    cmt->pop();
    ans = ansTmp;
  }

  void work() {
    ans = 0;
    workDFS(0);

    for (int i = 0; i < n; ++i) {
      printf("%d\\n", res[i]);
    }
  }
  ~Tree() {}
};

int main() {
  Tree t;
  t.work();
  return 0;
}

Error: -11

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>

using namespace std;

#define LL long long

const int dx[4] = {1, -1, 0, 0};
const int dy[4] = {0, 0, 1, -1};

LL mod(LL x, LL md) { return ((x % md) + md) % md; }

class Mint {
public:
  static LL md;
  LL x;
  Mint(LL _x) { x = mod(_x, md); }
  Mint(const Mint &y) { x = mod(y.x, md); }
};

void MintMyExgcd(LL a, LL b, LL &x, LL &y) {
  // solve equation ax + by = 1 (mod m)
  LL md = Mint::md;
  if (b == 0) {
    y = 0;
    x = 1;
    return;
  }
  MintMyExgcd(b, a % b, x, y);
  LL t = y;
  y = mod(x - (a / b) * y, md);
  x = t;
}

LL MintNY(LL x) {
  if (x == 0) {
    return 1;
  }
  LL md = Mint::md;
  LL a, b;
  MintMyExgcd(x, md, a, b);
  while (a < 0) {
    a += md;
  }
  return a;
}

/* LL gcd(LL a, LL b) {
        if (b == 0) {
                return a;
        }
        return gcd(b, a % b);
} */

Mint operator+(Mint a, Mint b) { return Mint(mod(a.x + b.x, Mint::md)); }
Mint operator-(Mint a, Mint b) { return Mint(mod(a.x - b.x, Mint::md)); }
Mint operator*(Mint a, Mint b) { return Mint(mod(a.x * b.x, Mint::md)); }
Mint operator/(Mint a, Mint b) {
  Mint c = Mint(MintNY(b.x));
  return Mint(mod(a.x * c.x, Mint::md));
}

Mint operator-(Mint a) { return Mint(-a.x); }
bool operator==(Mint a, Mint b) { return a.x == b.x; }
bool operator!=(Mint a, Mint b) { return a.x != b.x; }
bool operator>(Mint a, Mint b) { return a.x > b.x; }
bool operator<(Mint a, Mint b) { return a.x < b.x; }
bool operator>=(Mint a, Mint b) { return a.x >= b.x; }
bool operator<=(Mint a, Mint b) { return a.x <= b.x; }

void operator+=(Mint &a, Mint b) { a = a + b; }
void operator-=(Mint &a, Mint b) { a = a - b; }
void operator*=(Mint &a, Mint b) { a = a * b; }
void operator/=(Mint &a, Mint b) { a = a / b; }

ostream &operator<<(ostream &out, Mint a) {
  out << a.x;
  return out;
}

istream &operator>>(istream &in, Mint &a) {
  in >> a.x;
  return in;
}

Mint factorial(LL n) {
  if (n == 0) {
    return Mint(1);
  }
  Mint res = 1;
  for (LL i = 1; i <= n; ++i) {
    res *= i;
  }
  return res;
}
Mint multiRange(LL s, LL t) {
  Mint res = 1;
  for (LL i = s; i <= t; ++i) {
    res *= i;
  }
  return res;
}

Mint getC(LL n, LL k) {
  if (n - k < k) {
    return getC(n, n - k);
  }
  return multiRange(n - k + 1, n) / factorial(k);
}

Mint getA(LL n, LL k) { return multiRange(n - k + 1, n); }

Mint countNonNegativeDivision(LL n, LL k) { return getC(n + k - 1, k - 1); }
Mint countPositiveDivision(LL n, LL k) {
  if (n < k) {
    return 0;
  }
  if (k <= 0) {
    return 0;
  }
  return getC(n - 1, k - 1);
}
Mint quickMod(Mint a, LL b) {
  Mint res = 1;
  while (b > 0) {
    if (b % 2) {
      res *= a;
    }
    a *= a;
    b /= 2;
  }
  return res;
}

LL Mint::md = 1000000007;

class Edge {
public:
  int t, nxt;
  bool isDir;
  Edge(int _t, int _nxt, bool _isDir = false)
      : t(_t), nxt(_nxt), isDir(_isDir) {}
};
class Node {
public:
  Node *left, *right;
  int res;
  Node(int _res) : res(_res) { left = right = NULL; }
};

class ChairManTree {
public:
  int n;
  vector<Node *> v;
  int cur;
  Node *buildTree(int l, int r) {
    if (l == r) {
      return new Node(0);
    }
    Node *nd = new Node(0);
    int mid = (l + r) / 2;
    nd->left = buildTree(l, mid);
    nd->right = buildTree(mid + 1, r);
    return nd;
  }
  ChairManTree(int _n) : n(_n) {
    v.push_back(buildTree(0, n - 1));
    cur = 0;
  }
  void push(int x, int val) {
    Node *oldR = v[cur];
    Node *newR = new Node(max(v[cur]->res, val));
    int l = 0, r = n - 1;
    while (l < r) {
      int mid = (l + r) / 2;
      if (x > mid) {
        newR->left = oldR->left;
        newR->right = new Node(max(oldR->right->res, val));
        newR = newR->right;
        oldR = oldR->right;
        l = mid + 1;
      } else {
        newR->right = oldR->right;
        newR->left = new Node(max(oldR->left->res, val));
        newR = newR->left;
        oldR = oldR->left;
        r = mid;
      }
    }
  }
  int ask(Node *rr, int l, int r, int x) {
    if (r < x) {
      return rr->res;
    }
    if (l == r) {
      return -1;
    }
    int mid = (l + r) / 2;
    if (x > mid) {
      return max(rr->left->res, ask(rr->right, mid + 1, r, x));
    } else {
      return ask(rr->left, l, mid, x);
    }
  }
  int query(int x) {
    Node *r = v[cur];
    int res = 0;
    return ask(r, 0, n - 1, x) + 1;
  }
  void pop() { cur -= 1; }
};

class Nums {
public:
  int idx, x;
  Nums(int _idx, int _x) : x(_x), idx(_idx) {}
};

bool cmp(const Nums &a, const Nums &b) { return a.x < b.x; }

vector<int> discretize(vector<int> &x, int &maxCur) {
  // cout << endl;
  vector<Nums> a;
  for (int i = 0; i < x.size(); ++i) {
    a.push_back(Nums(i, x[i]));
  }
  sort(a.begin(), a.end(), cmp);
  int cur = 0;
  vector<int> res(a.size());
  for (int i = 0; i < a.size(); ++i) {
    // cout << a[i].idx << ' ' << a[i].x << endl;
    if (i == 0 || a[i].x == a[i - 1].x) {

    } else {
      ++cur;
    }
    res[a[i].idx] = cur;
  }
  maxCur = cur;
  return res;
}

class Tree {
public:
  int n;
  vector<Edge> e;
  int edgeN;
  vector<int> h;
  vector<int> s, f;
  vector<int> c;
  vector<int> cS;
  vector<int> res;
  int root;
  vector<bool> vis;
  vector<int> a;
  ChairManTree *cmt;
  int maxCur;

  void addEdge(int u, int v) {
    // printf("addEdge(%d, %d)", u, v);
    e.push_back(Edge(v, h[u]));
    h[u] = edgeN++;
    e.push_back(Edge(u, h[v]));
    h[v] = edgeN++;
  }

  void initDFS(int r) {
    s[r] = 1;
    vis[r] = true;
    for (int p = h[r]; p != -1; p = e[p].nxt) {
      int t = e[p].t;
      // printf("edge between (%d, %d)\\n", r, t);
      if (vis[t]) {
        e[p].isDir = false;
        continue;
      }
      e[p].isDir = true;
      f[t] = r;
      initDFS(t);
      s[r] += s[t];
    }
  }

  void initialize(int _root = 0) {
    root = _root;
    for (int i = 0; i < n; ++i) {
      s.push_back(0);
      f.push_back(-1);
      vis.push_back(false);
    }
    initDFS(root);
  }

  void printVector(vector<int> &x, string name) {
    cout << name << ": ";
    for (int i = 0; i < x.size(); ++i) {
      cout << x[i] << ' ';
    }
    cout << endl;
  }

  void checkOutput() {
    // printVector(s, "s");
    // printVector(f, "f");
    // printVector(h, "h");
    // cout << "root = " << root << endl;
  }

  Tree() {
    scanf("%d", &n);
    edgeN = 0;

    h.clear();
    for (int i = 0; i < n; ++i) {
      h.push_back(-1);
      c.push_back(0);
    }

    for (int i = 0; i < n; ++i) {
      scanf("%d", &c[i]);
      // c[i] -= 1;
    }

    c = discretize(c, maxCur);
    // for (int i = 0; i < c.size(); ++i) {
    // 	cout << c[i] << ' ';

    // }
    // cout << endl;

    int u, v;
    for (int i = 0; i < n - 1; ++i) {
      scanf("%d%d", &u, &v);
      addEdge(u - 1, v - 1);
    }

    initialize();
    checkOutput();
    res = vector<int>(n);
    cmt = new ChairManTree(maxCur + 1);
  }

  void workDFS(int r) {
    res[r] = cmt->query(c[r]);
    cmt->push(c[r], res[r]);
    for (int p = h[r]; p != -1; p = e[p].nxt) {
      if (e[p].isDir) {
        workDFS(e[p].t);
      }
    }
    cmt->pop();
  }

  void work() {
    workDFS(0);

    for (int i = 0; i < n; ++i) {
      printf("%d\\n", res[i]);
    }
  }
  ~Tree() {}
};

int main() {
  Tree t;
  t.work();
  return 0;
}