Problem p02698 (C++)

Buggy submission (status: Runtime Error):
// https://www.codechef.com/viewsolution/30791639

#include <bits/stdc++.h>
#define FAST                                                                   \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL);
typedef long long ll;
typedef long double ld;
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define mod 1000000007
#define inf 1000000000000000
#define bpc(x) __builtin_popcountll(x)
#define autoit(x, it) for (auto it = x.begin(); it != x.end(); it++)
#define rep(n) for (ll i = 0; i < n; i++)
#define repi(i, n) for (ll i = 0; i < n; i++)

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ordered_set                                                            \
  tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>

using namespace std;

#define N 2000

ll val[N];
ll fans[N];

ll que(ll st[], ll l, ll r, ll l1, ll r1, ll i) {
  if (l > r1 || l1 > r)
    return 0;
  if (l >= l1 && r <= r1)
    return st[i];
  ll mid = (l + r) / 2;

  return max(que(st, l, mid, l1, r1, 2 * i + 1),
             que(st, mid + 1, r, l1, r1, 2 * i + 2));
}

void upd(ll st[], ll l, ll r, ll l1, ll i, ll val) {
  if (l > l1 || r < l1)
    return;
  if (l == r) {
    st[i] = val;
    return;
  }

  ll mid = (l + r) / 2;
  upd(st, l, mid, l1, 2 * i + 1, val);
  upd(st, mid + 1, r, l1, 2 * i + 2, val);

  st[i] = max(st[2 * i + 1], st[2 * i + 2]);
}

void dfs(ll curr, vector<ll> v[], ll st[], ll par, ll lim) {
  ll prev = que(st, 0, lim, val[curr], val[curr], 0);
  ll now = que(st, 0, lim, 0, val[curr] - 1, 0) + 1;
  fans[curr] = max(st[0], now);
  if (now > prev) {

    upd(st, 0, lim, val[curr], 0, now);

    autoit(v[curr], it) {
      if (*it == par)
        continue;
      dfs(*it, v, st, curr, lim);
    }

    upd(st, 0, lim, val[curr], 0, prev);

  }

  else {
    autoit(v[curr], it) {
      if (*it == par)
        continue;
      dfs(*it, v, st, curr, lim);
    }
  }
}

int main() {
  FAST /**/

      ll n;
  cin >> n;

  rep(n) cin >> val[i];
  map<ll, ll> comp;
  rep(n) comp[val[i]] = 1;
  ll curr = 0;
  autoit(comp, it) it->ss = curr++;
  rep(n) val[i] = comp[val[i]];

  vector<ll> v[n];
  rep(n - 1) {
    ll a, b;
    cin >> a >> b;
    a--, b--;
    v[a].pb(b);
    v[b].pb(a);
  }

  ll lim = (comp.size());

  ll ht = ceil(log2(lim));
  // cout<<"ht = "<<ht<<"\n";
  ht = (1ll << (ht + 1)) - 1;
  ll st[ht];
  memset(st, 0, sizeof(st));

  dfs(0, v, st, -1, lim - 1);
  rep(n) cout << fans[i] << "\n";

  return 0;
}


Fixed submission:
// https://www.codechef.com/viewsolution/30791639

#include <bits/stdc++.h>
#define FAST                                                                   \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL);
typedef long long ll;
typedef long double ld;
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define mod 1000000007
#define inf 1000000000000000
#define bpc(x) __builtin_popcountll(x)
#define autoit(x, it) for (auto it = x.begin(); it != x.end(); it++)
#define rep(n) for (ll i = 0; i < n; i++)
#define repi(i, n) for (ll i = 0; i < n; i++)

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ordered_set                                                            \
  tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>

using namespace std;

#define N 200005

ll val[N];
ll fans[N];

ll que(ll st[], ll l, ll r, ll l1, ll r1, ll i) {
  if (l > r1 || l1 > r)
    return 0;
  if (l >= l1 && r <= r1)
    return st[i];
  ll mid = (l + r) / 2;

  return max(que(st, l, mid, l1, r1, 2 * i + 1),
             que(st, mid + 1, r, l1, r1, 2 * i + 2));
}

void upd(ll st[], ll l, ll r, ll l1, ll i, ll val) {
  if (l > l1 || r < l1)
    return;
  if (l == r) {
    st[i] = val;
    return;
  }

  ll mid = (l + r) / 2;
  upd(st, l, mid, l1, 2 * i + 1, val);
  upd(st, mid + 1, r, l1, 2 * i + 2, val);

  st[i] = max(st[2 * i + 1], st[2 * i + 2]);
}

void dfs(ll curr, vector<ll> v[], ll st[], ll par, ll lim) {
  ll prev = que(st, 0, lim, val[curr], val[curr], 0);
  ll now = que(st, 0, lim, 0, val[curr] - 1, 0) + 1;
  fans[curr] = max(st[0], now);
  if (now > prev) {

    upd(st, 0, lim, val[curr], 0, now);

    autoit(v[curr], it) {
      if (*it == par)
        continue;
      dfs(*it, v, st, curr, lim);
    }

    upd(st, 0, lim, val[curr], 0, prev);

  }

  else {
    autoit(v[curr], it) {
      if (*it == par)
        continue;
      dfs(*it, v, st, curr, lim);
    }
  }
}

int main() {
  FAST /**/

      ll n;
  cin >> n;

  rep(n) cin >> val[i];
  map<ll, ll> comp;
  rep(n) comp[val[i]] = 1;
  ll curr = 0;
  autoit(comp, it) it->ss = curr++;
  rep(n) val[i] = comp[val[i]];

  vector<ll> v[n];
  rep(n - 1) {
    ll a, b;
    cin >> a >> b;
    a--, b--;
    v[a].pb(b);
    v[b].pb(a);
  }

  ll lim = (comp.size());

  ll ht = ceil(log2(lim));
  // cout<<"ht = "<<ht<<"\n";
  ht = (1ll << (ht + 1)) - 1;
  ll st[ht];
  memset(st, 0, sizeof(st));

  dfs(0, v, st, -1, lim - 1);
  rep(n) cout << fans[i] << "\n";

  return 0;
}