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

#include <bits/stdc++.h>

using namespace std;
using ll = long long int;
constexpr ll M = 1e9 + 7;
inline ll sum_1(const ll n) { return ((n * (n + 1)) / 2) % M; }
inline ll sum_2(const ll n) { return ((n * (n + 1) * (2 * n + 1)) / 6) % M; }
inline ll sum_3(const ll n) {
  return (((n * (n + 1)) / 2) % M * ((n * (n + 1)) / 2) % M) % M;
}
inline ll sum_1(const ll i, const ll j) {
  return (sum_1(j) - sum_1(i - 1) + M) % M;
}
inline ll sum_2(const ll i, const ll j) {
  return (sum_2(j) - sum_2(i - 1) + M) % M;
}
inline ll sum_3(const ll i, const ll j) {
  return (sum_3(j) - sum_3(i - 1) + M) % M;
}

ll pow_f(ll b, ll e) {
  ll ans = 1;
  b = b % M;
  while (e) {
    if (e & 1) {
      ans = (ans * b) % M;
    }
    b = (b * b) % M;
    e >>= 1;
  }
  return ans;
}

ll nCr(ll n, ll r) {
  if (r > n || n < 0 || r < 0) {
    return 0;
  }
  if (n == r || r == 0) {
    return 1;
  }
  r = min(r, n - r);
  ll ans = 1;
  for (ll i = 1; i <= r; ++i) {
    ans = (ans * (n - i + 1)) / (i);
  }
  return ans;
}

ll nCr(tuple<ll, ll> t) {
  auto n = get<0>(t);
  auto k = get<1>(t);
  return nCr(n + k - 1, k);
}

template <typename T> void print(T v) { cout << v << " "; }

template <typename T> void print(vector<T> v) {
  for (auto &i : v) {
    print(i);
  }
  cout << endl;
}

class Tree {
  int n;
  vector<ll> a;
  vector<vector<int>> adj;
  vector<int> visited;
  vector<int> ans;

public:
  Tree(int n, vector<ll> &a)
      : n(n), a(a), adj(n), visited(n, false), ans(n, -1) {}

  void addEdge(int u, int v) {
    adj[u].push_back(v);
    adj[v].push_back(u);
  }

  int getAns(int i) { return ans[i]; }

  vector<tuple<int, int, int>>
      st; // {idx, original-value} if ori-val == -1, remove

  void dfs(int root, vector<pair<int, int>> &v) {
    visited[root] = true;

    // Add info for root
    if (v.empty()) {
      v.push_back({a[root], 1});
      st.push_back({v.size() - 1, -1, -1});
    } else {
      // Find subsequence with largest element less than curr ele
      if (v.back().first < a[root]) {
        v.push_back({a[root], v.back().second + 1});
        st.push_back({v.size() - 1, -1, -1});
      } else {
        int lo = 0;
        int hi = v.size() - 1;
        int mid;
        int ans;

        while (lo <= hi) {
          mid = lo + (hi - lo) / 2;
          if (v[mid].first >= a[root]) {
            ans = mid;
            hi = mid - 1;
          } else {
            lo = mid + 1;
          }
        }
        st.push_back({ans, v[ans].first, -1});
        v[ans].first = a[root];
      }
    }

    size_t pre_ = st.size();
    ans[root] = v.back().second;

    for (auto &i : adj[root]) {
      if (!visited[i]) {
        dfs(i, v);
        // Roll back
        for (auto j = st.end() - 1; st.size() != pre_; j = st.end() - 1) {
          auto x = get<0>(*j);
          auto y = get<1>(*j);
          if (y == -1) {
            v.pop_back();
          } else {
            v[x] = {y, v[x].second};
          }
          st.pop_back();
        }
      }
    }
  }
};

void solve() {
  int n;
  cin >> n;
  vector<ll> a(n);
  for (auto &i : a) {
    cin >> i;
  }

  Tree t(n, a);
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    cin >> u >> v;
    t.addEdge(u - 1, v - 1);
  }

  vector<pair<int, int>> v;
  t.dfs(0, v);

  for (int i = 0; i < n; ++i) {
    cout << t.getAns(i) << endl;
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
#ifdef D_LOCAL
  freopen("in.in", "r", stdin);
  freopen("out.out", "w", stdout);
#endif

  solve();

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;
using ll = long long int;
constexpr ll M = 1e9 + 7;
inline ll sum_1(const ll n) { return ((n * (n + 1)) / 2) % M; }
inline ll sum_2(const ll n) { return ((n * (n + 1) * (2 * n + 1)) / 6) % M; }
inline ll sum_3(const ll n) {
  return (((n * (n + 1)) / 2) % M * ((n * (n + 1)) / 2) % M) % M;
}
inline ll sum_1(const ll i, const ll j) {
  return (sum_1(j) - sum_1(i - 1) + M) % M;
}
inline ll sum_2(const ll i, const ll j) {
  return (sum_2(j) - sum_2(i - 1) + M) % M;
}
inline ll sum_3(const ll i, const ll j) {
  return (sum_3(j) - sum_3(i - 1) + M) % M;
}

ll pow_f(ll b, ll e) {
  ll ans = 1;
  b = b % M;
  while (e) {
    if (e & 1) {
      ans = (ans * b) % M;
    }
    b = (b * b) % M;
    e >>= 1;
  }
  return ans;
}

ll nCr(ll n, ll r) {
  if (r > n || n < 0 || r < 0) {
    return 0;
  }
  if (n == r || r == 0) {
    return 1;
  }
  r = min(r, n - r);
  ll ans = 1;
  for (ll i = 1; i <= r; ++i) {
    ans = (ans * (n - i + 1)) / (i);
  }
  return ans;
}

ll nCr(tuple<ll, ll> t) {
  auto n = get<0>(t);
  auto k = get<1>(t);
  return nCr(n + k - 1, k);
}

template <typename T> void print(T v) { cout << v << " "; }

template <typename T> void print(vector<T> v) {
  for (auto &i : v) {
    print(i);
  }
  cout << endl;
}

class Tree {
  int n;
  vector<ll> a;
  vector<vector<int>> adj;
  vector<int> visited;
  vector<int> ans;

public:
  Tree(int n, vector<ll> &a)
      : n(n), a(a), adj(n), visited(n, false), ans(n, -1) {}

  void addEdge(int u, int v) {
    adj[u].push_back(v);
    adj[v].push_back(u);
  }

  int getAns(int i) { return ans[i]; }

  void dfs(int root, vector<pair<int, int>> v) {
    visited[root] = true;

    // Add info for root
    if (v.empty()) {
      v.push_back({a[root], 1});
    } else {
      // Find subsequence with largest element less than curr ele
      if (v.back().first < a[root]) {
        v.push_back({a[root], v.back().second + 1});
      } else {
        int lo = 0;
        int hi = v.size() - 1;
        int mid;
        int ans;

        while (lo <= hi) {
          mid = lo + (hi - lo) / 2;
          if (v[mid].first >= a[root]) {
            ans = mid;
            hi = mid - 1;
          } else {
            lo = mid + 1;
          }
        }
        v[ans].first = a[root];
      }
    }

    ans[root] = v.back().second;

    for (auto &i : adj[root]) {
      if (!visited[i])
        dfs(i, v);
    }
  }
};

void solve() {
  int n;
  cin >> n;
  vector<ll> a(n);
  for (auto &i : a) {
    cin >> i;
  }

  Tree t(n, a);
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    cin >> u >> v;
    t.addEdge(u - 1, v - 1);
  }

  t.dfs(0, {});

  for (int i = 0; i < n; ++i) {
    cout << t.getAns(i) << endl;
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
#ifdef D_LOCAL
  freopen("in.in", "r", stdin);
  freopen("out.out", "w", stdout);
#endif

  solve();

  return 0;
}