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

// #include <bits/stdc++.h>

#include <algorithm>
#include <cassert>
#include <fstream>
#include <iostream>
#include <vector>

#define MAX_N 200000

#define xx first
#define yy second

using namespace std;

int n;
int v[MAX_N + 1];

int K;

struct aint {
  int st, dr, mx;
};

aint arb[MAX_N * 4 + MAX_N * 20 + 1];

int root[MAX_N + 1];

vector<int> g[MAX_N + 1];

void add(int a, int b) { g[a].push_back(b); }

pair<int, int> x[MAX_N + 1];

void readFile() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> x[i].xx;
    x[i].yy = i;
  }

  sort(x + 1, x + n + 1);

  int cr = 0;
  for (int i = 1; i <= n; i++) {
    if (x[i].xx != x[i - 1].xx)
      cr++;

    v[x[i].yy] = cr;
  }
  /*
      for(int i = 1; i<= n; i ++)
          cout <<v[i] << " ";
      cout << "\\n";*/

  for (int i = 1; i < n; i++) {
    int a, b;
    cin >> a >> b;
    add(a, b);
    add(b, a);
  }
}

void aloca(int &a) {
  if (a != 0)
    return;

  ++K;
  a = K;
}

int tata[MAX_N + 1];

int k;
int dfn[MAX_N + 1];

void dfs(int a, int t) {
  dfn[++k] = a;
  tata[a] = t;

  for (auto u : g[a]) {
    if (u != t) {
      dfs(u, a);
    }
  }
}

void build(int poz, int st, int dr, int a, int val) {
  if (st == a && dr == a) {
    arb[poz].mx = val;

    return;
  }

  int mid = (st + dr) >> 1;

  if (a <= mid) {
    if (arb[poz].st == 0) {
      K++;
      arb[poz].st = K;
    }

    build(arb[poz].st, st, mid, a, val);
  }

  else {
    if (arb[poz].dr == 0) {
      K++;
      arb[poz].dr = K;
    }
    build(arb[poz].dr, mid + 1, dr, a, val);
  }

  arb[poz].mx = max(arb[arb[poz].st].mx, arb[arb[poz].dr].mx);
}

int getMax(int poz, int st, int dr, int a, int b) {
  if (poz == 0)
    return 0;

  if (st == a && dr == b) {
    return arb[poz].mx;
  }

  int mid = (st + dr) >> 1;

  if (b <= mid)
    return getMax(arb[poz].st, st, mid, a, b);

  if (a > mid)
    return getMax(arb[poz].dr, mid + 1, dr, a, b);

  if (a <= mid && b > mid) {
    int v1 = getMax(arb[poz].st, st, mid, a, mid);
    int v2 = getMax(arb[poz].dr, mid + 1, dr, mid + 1, b);

    return max(v1, v2);
  }

  assert(1 == 0);

  return 0;
}

int upd(int poz2, int st, int dr, int a, int val) {
  ++K;
  int poz1 = K;
  if (st == a && dr == a) {
    arb[poz1].mx = max(val, arb[poz2].mx);
    arb[poz1].st = arb[poz2].st;
    arb[poz1].dr = arb[poz2].dr;

    return poz1;
  }

  int mid = (st + dr) >> 1;

  if (a <= mid) {
    arb[poz1].st = upd(arb[poz2].st, st, mid, a, val);

    arb[poz1].dr = arb[poz2].dr;
  }

  else {
    arb[poz1].dr = upd(arb[poz2].dr, mid + 1, dr, a, val);

    arb[poz1].st = arb[poz2].st;
  }

  arb[poz1].mx = max({arb[arb[poz1].st].mx, arb[arb[poz1].dr].mx,
                      arb[arb[poz2].st].mx, arb[arb[poz2].dr].mx});

  return poz1;
}

int rz[MAX_N + 1];

void solve() {
  dfs(1, -1);

  cout << "1\\n";

  aloca(root[1]);
  for (int i = 1; i <= n; i++)
    build(root[1], 1, n, i, 0);

  build(root[1], 1, n, v[1], 1);

  for (int j = 2; j <= n; j++) {
    int i = dfn[j];

    int rez = getMax(root[tata[i]], 1, n, 1, v[i] - 1) + 1;
    root[i] = upd(root[tata[i]], 1, n, v[i], rez);

    rz[i] = max(rez, rz[tata[i]]);
  }

  for (int i = 2; i <= n; i++)
    cout << rz[i] << "\\n";
}

int main() {
  readFile();

  solve();

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define MAX_N 200000

#define xx first
#define yy second

using namespace std;

int n;
int v[MAX_N + 1];

int K;

struct aint {
  int st, dr, mx;
};

aint arb[MAX_N * 4 + MAX_N * 20 + 1];

int root[MAX_N + 1];

vector<int> g[MAX_N + 1];

void add(int a, int b) { g[a].push_back(b); }

pair<int, int> x[MAX_N + 1];

void readFile() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> x[i].xx;
    x[i].yy = i;
  }

  sort(x + 1, x + n + 1);

  int cr = 0;
  for (int i = 1; i <= n; i++) {
    if (x[i].xx != x[i - 1].xx)
      cr++;

    v[x[i].yy] = cr;
  }
  /*
      for(int i = 1; i<= n; i ++)
          cout <<v[i] << " ";
      cout << "\\n";*/

  for (int i = 1; i < n; i++) {
    int a, b;
    cin >> a >> b;
    add(a, b);
    add(b, a);
  }
}

void aloca(int &a) {
  if (a != 0)
    return;

  ++K;
  a = K;
}

int tata[MAX_N + 1];

int k;
int dfn[MAX_N + 1];

void dfs(int a, int t) {
  dfn[++k] = a;
  tata[a] = t;

  for (auto u : g[a]) {
    if (u != t) {
      dfs(u, a);
    }
  }
}

void build(int poz, int st, int dr, int a, int val) {
  if (st == a && dr == a) {
    arb[poz].mx = val;

    return;
  }

  int mid = (st + dr) >> 1;

  if (a <= mid) {
    if (arb[poz].st == 0) {
      K++;
      arb[poz].st = K;
    }

    build(arb[poz].st, st, mid, a, val);
  }

  else {
    if (arb[poz].dr == 0) {
      K++;
      arb[poz].dr = K;
    }
    build(arb[poz].dr, mid + 1, dr, a, val);
  }

  arb[poz].mx = max(arb[arb[poz].st].mx, arb[arb[poz].dr].mx);
}

int getMax(int poz, int st, int dr, int a, int b) {
  if (st == a && dr == b) {
    return arb[poz].mx;
  }

  int mid = (st + dr) >> 1;

  if (b <= mid)
    return getMax(arb[poz].st, st, mid, a, b);

  if (a > mid)
    return getMax(arb[poz].dr, mid + 1, dr, a, b);

  if (a <= mid && b > mid) {
    int v1 = getMax(arb[poz].st, st, mid, a, mid);
    int v2 = getMax(arb[poz].dr, mid + 1, dr, mid + 1, b);

    return max(v1, v2);
  }

  assert(1 == 0);

  return 0;
}

int upd(int poz2, int st, int dr, int a, int val) {
  ++K;
  int poz1 = K;
  if (st == a && dr == a) {
    arb[poz1].mx = max(val, arb[poz2].mx);
    arb[poz1].st = arb[poz2].st;
    arb[poz1].dr = arb[poz2].dr;

    return poz1;
  }

  int mid = (st + dr) >> 1;

  if (a <= mid) {
    arb[poz1].st = upd(arb[poz2].st, st, mid, a, val);

    arb[poz1].dr = arb[poz2].dr;
  }

  else {
    arb[poz1].dr = upd(arb[poz2].dr, mid + 1, dr, a, val);

    arb[poz1].st = arb[poz2].st;
  }

  arb[poz1].mx = max({arb[arb[poz1].st].mx, arb[arb[poz1].dr].mx,
                      arb[arb[poz2].st].mx, arb[arb[poz2].dr].mx});

  return poz1;
}

int rz[MAX_N + 1];

void solve() {
  dfs(1, -1);

  cout << "1\\n";

  aloca(root[1]);
  for (int i = 1; i <= n; i++)
    build(root[1], 1, n, i, 0);

  build(root[1], 1, n, v[1], 1);

  for (int j = 2; j <= n; j++) {
    int i = dfn[j];

    //        cout << " SAUNTEM " << i << " " << v[i] << "\\n";

    int rez = getMax(root[tata[i]], 1, n, 1, v[i] - 1) + 1;
    root[i] = upd(root[tata[i]], 1, n, v[i], rez);

    rz[i] = rez;
  }

  for (int i = 2; i <= n; i++)
    cout << rz[i] << "\\n";
}

int main() {
  readFile();

  solve();

  return 0;
}