Problem p02698 (C++)

Buggy submission (status: Runtime Error):
#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace __gnu_pbds;
using namespace __gnu_cxx;
using namespace std;
using ll = long long;

#define eb emplace_back
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define len(v) ((int)v.size())
#define all(v) v.begin(), v.end()
#define precision(n) fixed << setprecision(n)

#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) 42
#endif

void io() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
}

template <typename T>
using oset =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T>
using MinPriorityQueue = priority_queue<T, vector<T>, greater<T>>;
template <typename T> void done(T ans) {
  cout << ans << "\n";
  exit(0);
}

template <typename A> istream &operator>>(istream &input, vector<A> &x) {
  for (auto &i : x)
    input >> i;
  return input;
}

template <typename A> ostream &operator<<(ostream &output, vector<A> &x) {
  for (auto &i : x)
    output << i << ' ';
  return output;
}

const int mod = 1e9;
const int N = 3e5 + 5;

auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937_64 mt(seed);

template <typename T> long long myrand(T m) {
  long long mod = m;
  long long x = mt() % mod;

  return x;
}

int a[N];
vector<int> ans(N);
vector<int> adj[N];
multiset<int> s;

void dfs(int node, int parent = 0) {
  s.insert(a[node]);
  int del = -1;
  // auto it = s.upper_bound(a[node]);
  auto it = s.lower_bound(a[node]);

  if (++it != s.end()) {
    del = *it;
    s.erase(it);
  }
  ans[node] = s.size();

  for (auto child : adj[node])
    if (child != parent)
      dfs(child, node);

  if (del != -1)
    s.insert(del);

  s.erase(s.find(a[node]));
}
vector<int> lis;
void dfs2(int node, int parent = 0) {
  auto it = lower_bound(lis.begin(), lis.end(), a[node]);
  int del = -1;
  if (it == lis.end()) {
    del = 1;
    lis.push_back(a[node]);
  } else {
    del = *it;
    *it = a[node];
  }

  ans[node - 1] = lis.size();

  for (auto child : adj[node])
    if (child != parent)
      dfs2(child, node);

  if (del == 1)
    lis.pop_back();
  else
    *it = del;
}
void dfs3(int node, int parent = -1) {
  int k = lower_bound(lis.begin(), lis.end(), a[node]) - lis.begin();
  int x = lis[k];
  lis[k] = a[node];
  ans[node - 1] = lower_bound(lis.begin(), lis.end(), INT_MAX) - lis.begin();
  for (int v : adj[node]) {
    if (v != parent) {
      dfs3(v, node);
    }
  }
  lis[k] = x;
}

int main() {
  io();
  int n, m, q;
  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> a[i];
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  // lis.assign(n + 4, INT_MAX);
  dfs3(1);
  ans.resize(n);
  cout << ans << " ";
  // while(q--) {
  //     int x;
  //     cin >> x;
  //     cout << ans[x] << "\n";
  // }
}


Fixed submission:
#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>

using namespace __gnu_pbds;
using namespace __gnu_cxx;
using namespace std;
using ll = long long;

#define eb emplace_back
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define len(v) ((int)v.size())
#define all(v) v.begin(), v.end()
#define precision(n) fixed << setprecision(n)

#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) 42
#endif

void io() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
}

template <typename T>
using oset =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T>
using MinPriorityQueue = priority_queue<T, vector<T>, greater<T>>;
template <typename T> void done(T ans) {
  cout << ans << "\n";
  exit(0);
}

template <typename A> istream &operator>>(istream &input, vector<A> &x) {
  for (auto &i : x)
    input >> i;
  return input;
}

template <typename A> ostream &operator<<(ostream &output, vector<A> &x) {
  for (auto &i : x)
    output << i << ' ';
  return output;
}

const int mod = 1e9;
const int N = 3e5 + 5;

auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937_64 mt(seed);

template <typename T> long long myrand(T m) {
  long long mod = m;
  long long x = mt() % mod;

  return x;
}

int a[N];
vector<int> ans(N);
vector<int> adj[N];
multiset<int> s;

void dfs(int node, int parent = 0) {
  s.insert(a[node]);
  int del = -1;
  // auto it = s.upper_bound(a[node]);
  auto it = s.lower_bound(a[node]);

  if (++it != s.end()) {
    del = *it;
    s.erase(it);
  }
  ans[node] = s.size();

  for (auto child : adj[node])
    if (child != parent)
      dfs(child, node);

  if (del != -1)
    s.insert(del);

  s.erase(s.find(a[node]));
}
vector<int> lis;
void dfs2(int node, int parent = 0) {
  auto it = lower_bound(lis.begin(), lis.end(), a[node]);
  int del = -1;
  if (it == lis.end()) {
    del = 1;
    lis.push_back(a[node]);
  } else {
    del = *it;
    *it = a[node];
  }

  ans[node - 1] = lis.size();

  for (auto child : adj[node])
    if (child != parent)
      dfs2(child, node);

  if (del == 1)
    lis.pop_back();
  else
    *it = del;
}
void dfs3(int node, int parent = -1) {
  int k = lower_bound(lis.begin(), lis.end(), a[node]) - lis.begin();
  int x = lis[k];
  lis[k] = a[node];
  ans[node - 1] = lower_bound(lis.begin(), lis.end(), INT_MAX) - lis.begin();
  for (int v : adj[node]) {
    if (v != parent) {
      dfs3(v, node);
    }
  }
  lis[k] = x;
}

int main() {
  io();
  int n, m, q;
  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> a[i];
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  lis.assign(n + 4, INT_MAX);
  dfs3(1);
  ans.resize(n);
  cout << ans << " ";
  // while(q--) {
  //     int x;
  //     cin >> x;
  //     cout << ans[x] << "\n";
  // }
}