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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;

#include <functional>
template <typename T> struct SegTree {
  int n;
  vector<T> node;
  T maxval;
  function<T(T, T)> fn;

public:
  SegTree(const vector<T> &v, T maxval0, function<T(T, T)> fn0) {
    n = 1;
    while ((1 << (n - 1)) < (int)v.size())
      n++;
    maxval = maxval0;
    fn = fn0;
    node.resize((1 << n) - 1, maxval);
    for (int i = 0; i < (int)v.size(); i++) {
      node[(1 << (n - 1)) - 1 + i] = v[i];
    }
    for (int i = (1 << (n - 1)) - 2; 0 <= i; i--) {
      node[i] = fn(node[2 * i + 1], node[2 * i + 2]);
    }
  }

  T query(int a, int b) {
    int l = (1 << (n - 1)) - 1 + a;
    int r = (1 << (n - 1)) - 1 + b;

    int m = 0;
    T ans = maxval;
    while (true) {
      if (r <= (l + 1) * (1 << m) - 1) {
        break;
      } else if (((l & 1) == 0) && ((l + 2) * (1 << m) - 1 <= r)) {
        ans = fn(ans, node[l]);
        ++l;
      } else if ((l + 3) * (1 << m) - 1 <= r) {
        l /= 2;
        ++m;
      } else if ((l + 2) * (1 << m) - 1 <= r) {
        ans = fn(ans, node[l]);
        ++l;
      } else {
        l = l * 2 + 1;
        --m;
      }
    }
    return ans;
  }

  T get(int p) { return node[(1 << (n - 1)) - 1 + p]; }

  int update(int p, T val) {
    int cur = (1 << (n - 1)) - 1 + p;
    node[cur] = val;
    for (int i = 0; i < n - 1; i++) {
      cur = (cur - 1) / 2;
      node[cur] = fn(node[2 * cur + 1], node[2 * cur + 2]);
    }
    return 0;
  }
};

int main() {
  int N;
  cin >> N;

  vector<ll> a(N);
  vector<vector<int>> p(N);

  for (int i = 0; i < N; i++)
    cin >> a[i];
  vector<ll> b(N);
  copy(a.begin(), a.end(), b.begin());
  sort(b.begin(), b.end());
  b.erase(unique(b.begin(), b.end()), b.end());
  // for(auto bi:b) cout << bi << " " ; cout << endl;
  for (auto &ai : a)
    ai = distance(b.begin(), lower_bound(b.begin(), b.end(), ai));
  // for(auto bi:a) cout << bi << " " ; cout << endl;

  for (int i = 0; i < N - 1; i++) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    p[u].push_back(v);
    p[v].push_back(u);
  }

  int ni = 0;
  vector<int> r(N, 0);
  vector<int> c(N, 0);
  SegTree<int> st(r, 0, [](int l0, int r0) { return max(l0, r0); });
  r[ni] = 1;

  deque<pair<int, int>> q;
  q.push_back(make_pair(ni, 1));
  st.update(a[ni], 1);

  while (!q.empty()) {
    pair<int, int> from = q.back();
    int f = 0;
    // cout << from.first << endl;
    for (; c[from.first] < p[from.first].size(); c[from.first]++) {
      int to = p[from.first][c[from.first]];
      if (r[to] != 0)
        continue;
      q.push_back(make_pair(to, st.get(a[to])));
      st.update(a[to], max(st.get(a[to]), st.query(0, a[to]) + 1));
      r[to] = st.node[0];
      // cout << to << " ";
      // for(auto qi:q) cout << qi.first << "(" << qi.second << ") "; cout <<
      // endl; for(int i=0; i<N ;i++) cout << st.get(i) << " "; cout << endl;
      f = 1;
      break;
    }
    if (f == 0) {
      st.update(a[from.first], from.second);
      q.pop_back();
    }
  }

  for (int i = 0; i < N; i++)
    cout << r[i] << endl;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;

#include <functional>
template <typename T> struct SegTree {
  int n;
  vector<T> node;
  T maxval;
  function<T(T, T)> fn;

public:
  SegTree(const vector<T> &v, T maxval0, function<T(T, T)> fn0) {
    n = 1;
    while ((1 << (n - 1)) < (int)v.size())
      n++;
    maxval = maxval0;
    fn = fn0;
    node.resize((1 << n) - 1, maxval);
    for (int i = 0; i < (int)v.size(); i++) {
      node[(1 << (n - 1)) - 1 + i] = v[i];
    }
    for (int i = (1 << (n - 1)) - 2; 0 <= i; i--) {
      node[i] = fn(node[2 * i + 1], node[2 * i + 2]);
    }
  }

  T query(int a, int b) {
    int l = (1 << (n - 1)) - 1 + a;
    int r = (1 << (n - 1)) - 1 + b;

    int m = 0;
    T ans = maxval;
    while (true) {
      if (r <= (l + 1) * (1 << m) - 1) {
        break;
      } else if (((l & 1) == 0) && ((l + 2) * (1 << m) - 1 <= r)) {
        ans = fn(ans, node[l]);
        ++l;
      } else if ((l + 3) * (1 << m) - 1 <= r) {
        l /= 2;
        ++m;
      } else if ((l + 2) * (1 << m) - 1 <= r) {
        ans = fn(ans, node[l]);
        ++l;
      } else {
        l = l * 2 + 1;
        --m;
      }
    }
    return ans;
  }

  T get(int p) { return node[(1 << (n - 1)) - 1 + p]; }

  int update(int p, T val) {
    int cur = (1 << (n - 1)) - 1 + p;
    node[cur] = val;
    for (int i = 0; i < n - 1; i++) {
      cur = (cur - 1) / 2;
      node[cur] = fn(node[2 * cur + 1], node[2 * cur + 2]);
    }
    return 0;
  }
};

int main() {
  int N;
  cin >> N;

  vector<ll> a(N);
  vector<vector<int>> p(N);

  for (int i = 0; i < N; i++)
    cin >> a[i];
  vector<ll> b(N);
  copy(a.begin(), a.end(), b.begin());
  sort(b.begin(), b.end());
  b.erase(unique(b.begin(), b.end()), b.end());
  // for(auto bi:b) cout << bi << " " ; cout << endl;
  for (auto &ai : a)
    ai = distance(b.begin(), lower_bound(b.begin(), b.end(), ai));
  // for(auto bi:a) cout << bi << " " ; cout << endl;

  for (int i = 0; i < N - 1; i++) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    p[u].push_back(v);
    p[v].push_back(u);
  }

  int ni = 0;
  vector<int> r(N, 0);
  SegTree<int> st(r, 0, [](int l0, int r0) { return max(l0, r0); });
  r[ni] = 1;

  deque<pair<int, int>> q;
  q.push_back(make_pair(ni, 1));
  st.update(a[ni], 1);

  while (!q.empty()) {
    pair<int, int> from = q.back();
    int f = 0;
    // cout << from.first << endl;
    for (auto to : p[from.first]) {
      if (r[to] != 0)
        continue;
      q.push_back(make_pair(to, st.get(a[to])));
      st.update(a[to], max(st.get(a[to]), st.query(0, a[to]) + 1));
      r[to] = st.node[0];
      // cout << to << " ";
      // for(auto qi:q) cout << qi.first << "(" << qi.second << ") "; cout <<
      // endl; for(int i=0; i<N ;i++) cout << st.get(i) << " "; cout << endl;
      f = 1;
      break;
    }
    if (f == 0) {
      st.update(a[from.first], from.second);
      q.pop_back();
    }
  }

  for (int i = 0; i < N; i++)
    cout << r[i] << endl;
}