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

// Optimise
#include <bits/stdc++.h>
using namespace std;

#ifdef LOCAL
#include "/home/shahraaz/bin/debug.h"
#else
#define db(...)
#endif

using ll = long long;
#define f first
#define s second
#define pb push_back
#define all(v) v.begin(), v.end()

const int NAX = 2e5 + 5, MOD = 1000000007;

struct Node {
  long long val;
  Node(long long one = 0) : val(one) {}
  Node operator+(const Node &rhs) {
    Node a = *this;
    a.val = max(a.val, rhs.val);
    return a;
  }
  Node lazylazyMerge(const Node &rhs) {
    Node a = *this;
    a.val = (a.val + rhs.val);
    return a;
  }
  Node seglazyMerge(const Node &rhs) {
    Node a = *this;
    a.val = (a.val + rhs.val);
    return a;
  }
  Node segSegMerge(const Node &rhs) {
    Node a = *this;
    a.val = max(a.val, rhs.val);
    return a;
  }
};

template <typename segNode> struct Segtree {
  vector<segNode> Seg, Lazy;
  vector<segNode> Base;
  vector<bool> isLazy;
  int n;
  Segtree(int _n = 2e5) {
    this->n = _n;
    Seg.resize(4 * _n + 10);
    Lazy.resize(4 * _n + 10);
    isLazy.resize(4 * _n + 10);
  }
  void merge(segNode &curr, segNode &l, segNode &r) { curr = l + r; }
  void propagate(int node, int L, int R) {
    if (isLazy[node]) {
      isLazy[node] = false;
      Seg[node] = Seg[node].seglazyMerge(Lazy[node]);
      if (L != R) {
        Lazy[2 * node] = Lazy[2 * node].lazylazyMerge(Lazy[node]);
        Lazy[2 * node + 1] = Lazy[2 * node + 1].lazylazyMerge(Lazy[node]);
        isLazy[2 * node] = true;
        isLazy[2 * node + 1] = true;
      }
      Lazy[node] = segNode();
    }
  }
  void build(int node, int start, int end) {
    if (start == end) {
      Seg[node] = Base[start];
      return;
    }
    int mid = (start + end) / 2;
    build(2 * node, start, mid);
    build(2 * node + 1, mid + 1, end);
    Seg[node] = Seg[2 * node].segSegMerge(Seg[2 * node + 1]);
  }
  void build(vector<segNode> &Arr) {
    Base = Arr;
    n = Arr.size();
    Seg.resize(4 * n + 10);
    Lazy.resize(4 * n + 10);
    isLazy.resize(4 * n + 10);
    build(1, 0, n - 1);
  }
  segNode Query(int node, int start, int end, int qstart, int qend) {
    propagate(node, start, end);
    if (qend < start || qstart > end || start > end)
      return segNode();
    if (qstart <= start && end <= qend)
      return Seg[node];
    int mid = (start + end) / 2;
    segNode l = Query(2 * node, start, mid, qstart, qend);
    segNode r = Query(2 * node + 1, mid + 1, end, qstart, qend);
    return l.segSegMerge(r);
  }
  segNode qQuery(int node, int start, int end, int pos) {
    propagate(node, start, end);
    if (start == end)
      return Seg[node];
    int mid = (start + end) / 2;
    if (pos <= mid)
      return qQuery(2 * node, start, mid, pos);
    return qQuery(2 * node + 1, mid + 1, end, pos);
  }
  void Update(int node, int start, int end, int qstart, int qend, segNode val) {
    propagate(node, start, end);
    if (qend < start || qstart > end || start > end)
      return;
    if (qstart <= start && end <= qend) {
      isLazy[node] = true;
      Lazy[node] = val;
      propagate(node, start, end);
      return;
    }
    int mid = (start + end) / 2;
    Update(2 * node, start, mid, qstart, qend, val);
    Update(2 * node + 1, mid + 1, end, qstart, qend, val);
    Seg[node] = Seg[2 * node].segSegMerge(Seg[2 * node + 1]);
  }
  void pUpdate(int node, int start, int end, int pos, segNode val) {
    propagate(node, start, end);
    if (start == end) {
      // isLazy[node] = true;
      // Lazy[node] = val;
      // propagate(node, start, end);
      Seg[node] = val;
      return;
    }
    int mid = (start + end) / 2;
    if (pos <= mid)
      pUpdate(2 * node, start, mid, pos, val);
    else
      pUpdate(2 * node + 1, mid + 1, end, pos, val);
    Seg[node] = Seg[2 * node].segSegMerge(Seg[2 * node + 1]);
  }
  segNode query(int pos) { return qQuery(1, 0, n - 1, pos); }
  segNode query(int left, int right) { return Query(1, 0, n - 1, left, right); }
  void update(int pos, segNode val) { pUpdate(1, 0, n - 1, pos, val); }
  void update(int start, int end, segNode val) {
    Update(1, 0, n - 1, start, end, val);
  }
};

vector<int> adj[NAX];
int a[NAX];
int res[NAX];
int n;

Segtree<Node> S(0);

class Solution {
private:
  void dfs(int node, int par) {
#ifdef LOCAL
    db(node, a[node]);
    for (size_t i = 0; i < n; i++)
      cout << S.query(i).val << ' ';
    cout << '\\n';
#endif
    auto prev = S.query(a[node]);
    res[node] = max(prev.val, S.query(0, a[node] - 1).val + 1);
    S.update(a[node], Node(res[node]));
    res[node] = max(res[node], res[par]);
    for (auto &x : adj[node]) {
      if (x == par)
        continue;
      dfs(x, node);
    }
    S.update(a[node], prev);
  }

public:
  Solution() {}
  ~Solution() {}
  void solveCase() {
    cin >> n;
    S = Segtree<Node>(n + 1);
    vector<int> x;
    for (size_t i = 0; i < n; i++) {
      cin >> a[i];
      x.pb(a[i]);
    }
    sort(all(x));
    x.erase(unique(all(x)), x.end());
    for (size_t i = 0; i < n; i++) {
      a[i] = lower_bound(all(x), a[i]) - x.begin();
      // cout << a[i] << ' ';
    }
    // cout << '\\n';
    for (size_t i = 1; i < n; i++) {
      int u, v;
      cin >> u >> v;
      --u, --v;
      adj[u].pb(v);
      adj[v].pb(u);
    }
    dfs(0, 0);
    for (size_t i = 0; i < n; i++) {
      cout << res[i] << '\\n';
    }
  }
};

int32_t main() {
#ifndef LOCAL
  ios_base::sync_with_stdio(0);
  cin.tie(0);
#endif
  int t = 1;
  // cin >> t;
  Solution mySolver;
  for (int i = 1; i <= t; ++i) {
    mySolver.solveCase();
#ifdef LOCAL
    cerr << "Case #" << i << ": Time "
         << chrono::duration<double>(chrono::steady_clock::now() - TimeStart)
                .count()
         << " s.\\n";
    TimeStart = chrono::steady_clock::now();
#endif
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
// #include <unordered_map>
// #include <unordered_set>
#define lowbit(x) (x & (-x))
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r) >> 1
#define lsn rt << 1
#define rsn rt << 1 | 1
#define Lson lsn, l, mid
#define Rson rsn, mid + 1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 2e5 + 7;
int N, head[maxN], cnt, a[maxN], Lsan[maxN], _UP;
struct Eddge {
  int nex, to;
  Eddge(int a = -1, int b = 0) : nex(a), to(b) {}
} edge[maxN << 1];
inline void addEddge(int u, int v) {
  edge[cnt] = Eddge(head[u], v);
  head[u] = cnt++;
}
inline void _add(int u, int v) {
  addEddge(u, v);
  addEddge(v, u);
}
int ans[maxN];
int tree[maxN << 2] = {0};
struct heap {
  priority_queue<int> Que, Del;
  inline bool empty() {
    while (!Que.empty() && !Del.empty() && Que.top() == Del.top()) {
      Que.pop();
      Del.pop();
    }
    return Que.empty();
  }
  inline void push(int val) { Que.push(val); }
  inline void clear(int val) { Del.push(val); }
  inline int size() { return (int)(Que.size() - Del.size()); }
  inline int top() {
    while (!Que.empty() && !Del.empty() && Que.top() == Del.top()) {
      Que.pop();
      Del.pop();
    }
    return Que.top();
  }
  inline void pop() {
    while (!Que.empty() && !Del.empty() && Que.top() == Del.top()) {
      Que.pop();
      Del.pop();
    }
    Que.pop();
  }
} st[maxN];
inline void pushup(int rt) { tree[rt] = max(tree[lsn], tree[rsn]); }
void Add(int rt, int l, int r, int qx, int val) {
  if (l == r) {
    st[l].push(val);
    tree[rt] = st[l].top();
    return;
  }
  int mid = HalF;
  if (qx <= mid)
    Add(Lson, qx, val);
  else
    Add(Rson, qx, val);
  pushup(rt);
}
void Del(int rt, int l, int r, int qx, int val) {
  if (l == r) {
    st[l].clear(val);
    if (st[l].empty())
      tree[rt] = 0;
    else
      tree[rt] = st[l].top();
    return;
  }
  int mid = HalF;
  if (qx <= mid)
    Del(Lson, qx, val);
  else
    Del(Rson, qx, val);
  pushup(rt);
}
int query(int rt, int l, int r, int ql, int qr) {
  if (ql <= l && qr >= r)
    return tree[rt];
  int mid = HalF;
  if (qr <= mid)
    return query(QL);
  else if (ql > mid)
    return query(QR);
  else
    return max(query(QL), query(QR));
}
void dfs(int u, int fa) {
  Add(1, 1, _UP, a[u], ans[u]);
  for (int i = head[u], v; ~i; i = edge[i].nex) {
    v = edge[i].to;
    if (v == fa)
      continue;
    ans[v] = query(1, 1, _UP, 1, a[v] - 1) + 1;
    dfs(v, u);
  }
  Del(1, 1, _UP, a[u], ans[u]);
}
inline void init() {
  cnt = 0;
  for (int i = 1; i <= N; i++)
    head[i] = -1;
}
int main() {
  scanf("%d", &N);
  init();
  for (int i = 1; i <= N; i++) {
    scanf("%d", &a[i]);
    Lsan[i] = a[i];
  }
  sort(Lsan + 1, Lsan + N + 1);
  _UP = (int)(unique(Lsan + 1, Lsan + N + 1) - Lsan - 1);
  for (int i = 1; i <= N; i++)
    a[i] = (int)(lower_bound(Lsan + 1, Lsan + _UP + 1, a[i]) - Lsan);
  for (int i = 1, u, v; i < N; i++) {
    scanf("%d%d", &u, &v);
    _add(u, v);
  }
  ans[1] = 1;
  dfs(1, 0);
  for (int i = 1; i <= N; i++)
    printf("%d\\n", ans[i]);
  return 0;
}