Problem p02698 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <stdio.h>
#include <stdlib.h>

#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <stdint.h>
#include <string.h>

#define _USE_MATH_DEFINES
#include <math.h>

#include <deque>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <algorithm>
#include <bitset>
#include <chrono>
#include <functional>
#include <random>

#define sqr(x) (x) * (x)

typedef unsigned int u32;
typedef int i32;
typedef unsigned long long int u64;
typedef int i64;
typedef uint16_t u16;
typedef int16_t i16;
typedef uint8_t u8;
typedef int8_t i8;

using namespace std;
using namespace std::chrono;

// const i64 mod = 1000000007ll;
const i64 smod = 998244353ll;
const i64 inf = 1'000'000'000'000'000'000ll + 7;
// const i64 inf = 1'000'000'007;

const long double eps = 1e-8;

struct segtree {
  using type = i32;
  const type zero = 0;

  inline type combine(type a, type b) { return max(a, b); }

  i64 n = 0;
  vector<type> st;

  void init(i64 size) {
    n = 1;
    while (n < size) {
      n *= 2;
    }
    st.assign(n * 2, zero);
  }

  void set(i64 i, type v, i64 x, i64 lx, i64 rx) {
    if (rx - lx == 1) {
      st[x] = v;
      return;
    }

    i64 m = (lx + rx) / 2;
    if (i < m) {
      set(i, v, x * 2 + 1, lx, m);
    } else {
      set(i, v, x * 2 + 2, m, rx);
    }

    st[x] = combine(st[x * 2 + 1], st[x * 2 + 2]);
  }

  void set(i64 i, type v) { set(i, v, 0, 0, n); }

  type calc(i64 l, i64 r, i64 x, i64 lx, i64 rx) {
    if (lx >= r || l >= rx) {
      return zero;
    }

    if (l <= lx && rx <= r) {
      return st[x];
    }

    i64 m = (lx + rx) / 2;
    type v1 = calc(l, r, x * 2 + 1, lx, m);
    type v2 = calc(l, r, x * 2 + 2, m, rx);
    return combine(v1, v2);
  }

  type calc(i64 l, i64 r) { return calc(l, r, 0, 0, n); }
};

const i64 MAXN = 2 * 100'000 + 6;

i64 n, m;
i64 a[MAXN];
vector<i64> e[MAXN];
map<i64, i64> z;

i64 r[MAXN];

segtree st;

void dfs(i64 c, i64 p, map<i64, vector<i64>> &q) {
  i64 v = 1;

  i64 t = st.calc(0, a[c]);
  v += t;

  q[a[c]].push_back(v);
  st.set(a[c], v);

  r[c] = st.calc(0, z.size());

  for (auto n : e[c]) {
    if (n == p) {
      continue;
    }
    dfs(n, c, q);
  }

  q[a[c]].pop_back();
  st.set(a[c], q[a[c]].size() ? q[a[c]].back() : 0);

  if (q[a[c]].empty()) {
    q.erase(a[c]);
  }
}

void dict() {
  vector<i64> q;
  for (i64 i = 1; i <= n; i++) {
    q.push_back(a[i]);
  }
  sort(q.begin(), q.end());

  for (auto t : q) {
    if (z.count(t)) {
      continue;
    }
    z[t] = z.size();
  }

  for (i64 i = 1; i <= n; i++) {
    a[i] = z[a[i]];
  }
}

int main(int argc, char *argv[]) {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout.precision(15);
  cout.setf(ios::fixed);

  cin >> n;

  for (i64 i = 1; i <= n; i++) {
    cin >> a[i];
  }

  for (i64 i = 1; i < n; i++) {
    i64 u, v;
    cin >> u >> v;

    e[u].push_back(v);
    e[v].push_back(u);
  }

  dict();
  st.init(z.size());

  map<i64, vector<i64>> q;
  dfs(1, 0, q);

  stringstream ss;
  for (i64 i = 1; i <= n; i++) {
    ss << r[i] << endl;
  }
  cout << ss.str();

  return 0;
}

Error: TLE

Fixed submission:

#include <stdio.h>
#include <stdlib.h>

#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <stdint.h>
#include <string.h>

#define _USE_MATH_DEFINES
#include <math.h>

#include <deque>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <algorithm>
#include <bitset>
#include <chrono>
#include <functional>
#include <random>

#define sqr(x) (x) * (x)

typedef unsigned int u32;
typedef int i32;
typedef unsigned long long int u64;
typedef long long int i64;
typedef uint16_t u16;
typedef int16_t i16;
typedef uint8_t u8;
typedef int8_t i8;

using namespace std;
using namespace std::chrono;

// const i64 mod = 1000000007ll;
const i64 smod = 998244353ll;
const i64 inf = 1'000'000'000'000'000'000ll + 7;
// const i64 inf = 1'000'000'007;

const long double eps = 1e-8;

const i64 MAXN = 2 * 100'000 + 6;

i64 n, m;
i64 a[MAXN];
vector<i64> e[MAXN];

i64 r[MAXN];

void dfs(i64 c, i64 p, map<i64, vector<i64>> &q) {
  auto it = q.lower_bound(a[c]);
  if (it == q.begin()) {
    q[a[c]].push_back(1);
  } else {
    i64 t = 0;
    for (auto nit = q.begin(); nit != it; nit++) {
      t = max(t, nit->second.back());
    }
    q[a[c]].push_back(1 + t);
  }

  for (auto &t : q) {
    r[c] = max(r[c], t.second.back());
  }

  for (auto n : e[c]) {
    if (n == p) {
      continue;
    }
    dfs(n, c, q);
  }

  q[a[c]].pop_back();
  if (q[a[c]].empty()) {
    q.erase(a[c]);
  }
}

int main(int argc, char *argv[]) {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout.precision(15);
  cout.setf(ios::fixed);

  cin >> n;

  for (i64 i = 1; i <= n; i++) {
    cin >> a[i];
  }

  for (i64 i = 1; i < n; i++) {
    i64 u, v;
    cin >> u >> v;

    e[u].push_back(v);
    e[v].push_back(u);
  }

  map<i64, vector<i64>> q;
  dfs(1, 0, q);

  stringstream ss;
  for (i64 i = 1; i <= n; i++) {
    ss << r[i] << endl;
  }
  cout << ss.str();

  return 0;
}