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

/* Manish Pant - insider_pants, hello_my_friend */

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;

#define F first
#define S second
#define endl "\\n"
#define pb push_back

typedef long long ll;
typedef long double ldob;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
  for (T i : v)
    os << i << " ";
  return os;
}
template <class T> ostream &operator<<(ostream &os, const set<T> &v) {
  for (T i : v)
    os << i << " ";
  return os;
}
template <class T> ostream &operator<<(ostream &os, const multiset<T> &v) {
  for (T i : v)
    os << i << " ";
  return os;
}
template <class T, class S>
ostream &operator<<(ostream &os, const pair<T, S> &v) {
  os << v.F << ' ' << v.S;
  return os;
}
template <class T, class S>
ostream &operator<<(ostream &os, const map<T, S> &v) {
  for (auto i : v)
    os << '(' << i.F << " => " << i.S << ')' << ' ';
  return os;
}

void fast() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
}

const int N = 2e5 + 5;
vector<vector<int>> v(N);
vector<int> val(N);
vector<int> pre(N);
vector<int> ans(N);
vector<int> segtree(4 * N);
int n, c = 1;

void update(int x, int val, int node = 0, int l = 0, int r = c) {
  if (l == r) {
    segtree[node] = max(segtree[node], val);
    return;
  }
  int mid = (l + r) >> 1;
  if (x <= mid)
    update(x, val, 2 * node + 1, l, mid);
  else
    update(x, val, 2 * node + 2, mid + 1, r);

  segtree[node] = max(segtree[2 * node + 1], segtree[2 * node + 2]);
}

void update2(int x, int val, int node = 0, int l = 0, int r = c) {
  if (l == r) {
    segtree[node] = val;
    return;
  }
  int mid = (l + r) >> 1;
  if (x <= mid)
    update2(x, val, 2 * node + 1, l, mid);
  else
    update2(x, val, 2 * node + 2, mid + 1, r);

  segtree[node] = max(segtree[2 * node + 1], segtree[2 * node + 2]);
}

int query(int x, int y, int node = 0, int l = 0, int r = c) {
  if (l > y || r < x || x > y)
    return 0;
  if (l >= x && r <= y) {
    return segtree[node];
  }
  int mid = (l + r) >> 1;
  return max(query(x, y, 2 * node + 1, l, mid),
             query(x, y, 2 * node + 2, mid + 1, r));
}

void dfs(int a, int par) {
  int temp = query(0, val[a] - 1);
  pre[a] = query(val[a], val[a]);
  update(val[a], temp + 1);
  ans[a] = query(0, c);

  for (int i : v[a]) {
    if (i == par)
      continue;
    dfs(i, a);
  }

  update2(val[a], pre[a]);
}

void solve() {
  map<int, int> m;
  for (int i = 1; i <= n; i++)
    m[val[i]] = 0;

  for (auto &i : m)
    i.S = c++;

  for (int i = 1; i <= n; i++)
    val[i] = m[val[i]];

  dfs(1, 0);

  for (int i = 1; i <= n; i++)
    cout << ans[i] << endl;
}

int main() {
  fast();
  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> val[i];
  for (int i = 1; i < n; i++) {
    int a, b;
    cin >> a >> b;
    v[a].pb(b);
    v[b].pb(a);
  }
  solve();
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
typedef long long ll;

#define pll pair<ll, ll>
#define ff first
#define snd second
#define pb push_back
#define vll vector<ll>
#define vpll vector<pll>
#define endl "\\n"
#define MOD 1000000007
using namespace std;

class segmentTree {
public:
  ll n;
  vll v;
  segmentTree(ll val) {
    n = val + 10;
    ll k = 4LL * (2e5 + 5);
    v.resize(k, 0);
  }

  ll getMin(ll qs, ll qe) { return get(0, n, qs, qe, 0); }

  void update(ll i, ll p) { upd(0, n, 0, i, p); }

private:
  void upd(ll low, ll high, ll pos, ll idx, ll new_val) {
    if (low == high && low == idx) {
      v[pos] = new_val;
      return;
    }
    ll mid = (low + high) / 2;
    ll left = (2 * pos) + 1;
    ll right = (2 * pos) + 2;
    if (idx <= mid)
      upd(low, mid, left, idx, new_val);
    else
      upd(mid + 1, high, right, idx, new_val);
    v[pos] = max(v[left], v[right]);
    return;
  }

  ll get(ll low, ll high, ll qs, ll qe, ll pos) {
    // If segment of this node is a part of given range, then return
    // the sum of the segmen
    if (qs <= low && qe >= high) {
      // cout<<pos<<" "<<s[pos]<<endl;
      return v[pos];
      // cout<<"pop";
    }
    // If segment of this node is outside the given range
    if (high < qs || low > qe)
      return 0;

    // If a part of this segment overlaps with the given range
    ll mid = (low + high) / 2;
    ll left = (2 * pos) + 1;
    ll right = (2 * pos) + 2;
    ll ans1 = get(low, mid, qs, qe, left);
    ll ans2 = get(mid + 1, high, qs, qe, right);
    return max(ans1, ans2);
    // cout<<pos<<" "<<ans<<endl;
  }
};

ll const N = 2e5 + 5;
vll a(N);
vector<vector<int>> v(N);
vector<ll> final(N);
ll c;

void dfs(int curr, segmentTree &s, int parent = 0) {
  ll ans = s.getMin(0, max(0LL, a[curr] - 1));
  ans++;

  ll prev = s.getMin(a[curr], a[curr]);
  s.update(a[curr], ans);
  final[curr] = s.getMin(0, c);
  for (int i = 0; i < v[curr].size(); i++) {
    if (v[curr][i] != parent) {
      dfs(v[curr][i], s, curr);
    }
  }
  s.update(a[curr], prev);
}

void solve() {
  ll n;
  cin >> n;
  map<ll, ll> m;
  ll maxi = -1;
  vll b(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    b[i] = a[i];
  }

  sort(b.begin() + 1, b.end());
  for (int i = 1; i <= n;) {
    int siz = m.size();
    m[b[i]] = siz;
    maxi = max(b[i], maxi);
    int j = i + 1;
    while (j <= n && b[j] == b[i]) {
      j++;
    }
    i = j;
  }

  c = m.size() - 1;
  for (int i = 1; i <= n; i++) {
    a[i] = m[a[i]];
  }

  for (int i = 0; i < n - 1; i++) {
    ll a, b;
    cin >> a >> b;
    v[a].pb(b);
    v[b].pb(a);
  }

  segmentTree s(maxi);
  dfs(1, s);
  for (int i = 1; i <= n; i++) {
    cout << final[i] << "\\n";
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int t = 1;
  // cin>>t;
  while (t--) {
    solve();
  }
  return 0;
}