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

#include <bits/stdc++.h>
#define FAST ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define dofloat cout << fixed << setprecision(8)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define bitcount __builtin_popcount
#define all(vec) vec.begin(), vec.end()
#define rall(vec) vec.rbegin(), vec.rend()
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<long long> vl;
typedef pair<long long, long long> pll;
typedef vector<pair<long long, long long>> vll;
typedef vector<pair<int, int>> vii;
typedef vector<int> vi;
typedef pair<int, int> ii;
const long long MOD = 1000000007;
const long long MAX = 100005;
const long double PI = 3.14159265359;
const long double G = 9.807;
const long long INF = 1e18;
const long double EPS = 1e-6;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
bool isprime(ll a) {
  if (a == 2)
    return 1;
  if (!(a & 1))
    return 0;
  for (ll i = 3; i * i <= a; i += 2)
    if (a % i == 0)
      return 0;
  return 1;
}
ll mpow(ll base, ll exponent, ll modulus) {
  if (modulus == 1)
    return 0;
  long long result = 1;
  base = base % modulus;
  while (exponent) {
    if (exponent % 2 == 1)
      result = (result * base) % modulus;
    exponent = exponent >> 1;
    base = (base * base) % modulus;
  }
  return result;
}
ll minv(ll a, ll mod) {
  ll _gcd = gcd(a, mod);
  assert(_gcd == 1);
  return mpow(a, mod - 2, mod);
}

/*
ll ncr(ll N,ll K){
  if(N<K)return 0;
  if(K==0)return 1;
  if(N==0)return 0;

  ll den=1;
  for(ll i=1;i<=K;i++)den*=i;
  ll num=1;
  while(K--){
    num*=N;
    if(num%den==0){
      num/=den;
      den=1;
    }
    N--;
  }

  return num;
}
*/
ll n;
vl g[2 * MAX];
ll ST[8 * MAX], A[2 * MAX];
ll a[2 * MAX];
map<ll, ll> M;
ll ans[2 * MAX];
multiset<ll> bigF[2 * MAX];

void build(ll node, ll lo, ll hi) {
  if (lo == hi) {
    ST[node] = A[lo];
    return;
  }
  ll mid = (lo + hi) >> 1;
  build(node << 1, lo, mid);
  build(node << 1 | 1, mid + 1, hi);
  ST[node] = ST[node << 1] + ST[node << 1 | 1];
}

void update(ll node, ll lo, ll hi, ll x, ll y) {
  if (lo == hi) {
    ST[node] = y;
    return;
  }
  ll mid = (lo + hi) >> 1;
  if (lo <= x and mid >= x) {
    update(node << 1, lo, mid, x, y);
  } else {
    update(node << 1 | 1, mid + 1, hi, x, y);
  }
  ST[node] = max(ST[node << 1], ST[node << 1 | 1]);
}

ll query(ll node, ll lo, ll hi, ll l, ll r) {
  if (lo > r or hi < l) {
    return 0;
  } else if (l <= lo and hi <= r) {
    return ST[node];
  }
  ll mid = (lo + hi) >> 1LL;
  ll p1 = query(node << 1, lo, mid, l, r);
  ll p2 = query(node << 1 | 1, mid + 1, hi, l, r);
  return max(p1, p2);
}

void dfs(ll u, ll p) {
  ll pos = M[a[u]];
  ll mx = query(1, 1, n, 1, pos - 1);
  ans[u] = mx + 1;
  bigF[pos].insert(ans[u]);
  update(1, 1, n, pos, ans[u]);
  for (auto v : g[u]) {
    if (v != p) {
      dfs(v, u);
    }
  }
  auto it = bigF[pos].find(ans[u]);
  bigF[pos].erase(it);
  if (bigF[pos].empty()) {
    update(1, 1, n, pos, 0);
  } else {
    update(1, 1, n, pos, *bigF[pos].rbegin());
  }
}

void solve(ll u, ll p, ll mx) {
  ans[u] = mx;
  for (auto v : g[u]) {
    if (v != p) {
      solve(v, u, max(mx, ans[v]));
    }
  }
}

int main() {
  FAST;
  cin >> n;
  for (ll i = 1; i <= n; ++i) {
    cin >> a[i];
    M[a[i]];
  }
  ll cur = 1;
  for (auto &it : M) {
    it.second = cur++;
  }
  for (ll i = 1; i <= n - 1; ++i) {
    ll u, v;
    cin >> u >> v;
    g[u].pb(v);
    g[v].pb(u);
  }
  dfs(1, 0);
  solve(1, 0, ans[1]);
  for (ll i = 1; i <= n; ++i)
    cout << ans[i] << '\\n';
  return 0;
}

/*
 WA? check edge cases, N=1,M=1 etc. Read code fully once and check all
 variables. Read the question again and see what you might have missed. Consider
 changing your solution or find more cases.
 */


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define FAST ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define dofloat cout << fixed << setprecision(8)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define bitcount __builtin_popcount
#define all(vec) vec.begin(), vec.end()
#define rall(vec) vec.rbegin(), vec.rend()
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<long long> vl;
typedef pair<long long, long long> pll;
typedef vector<pair<long long, long long>> vll;
typedef vector<pair<int, int>> vii;
typedef vector<int> vi;
typedef pair<int, int> ii;
const long long MOD = 1000000007;
const long long MAX = 100005;
const long double PI = 3.14159265359;
const long double G = 9.807;
const long long INF = 1e18;
const long double EPS = 1e-6;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
bool isprime(ll a) {
  if (a == 2)
    return 1;
  if (!(a & 1))
    return 0;
  for (ll i = 3; i * i <= a; i += 2)
    if (a % i == 0)
      return 0;
  return 1;
}
ll mpow(ll base, ll exponent, ll modulus) {
  if (modulus == 1)
    return 0;
  long long result = 1;
  base = base % modulus;
  while (exponent) {
    if (exponent % 2 == 1)
      result = (result * base) % modulus;
    exponent = exponent >> 1;
    base = (base * base) % modulus;
  }
  return result;
}
ll minv(ll a, ll mod) {
  ll _gcd = gcd(a, mod);
  assert(_gcd == 1);
  return mpow(a, mod - 2, mod);
}

/*
ll ncr(ll N,ll K){
  if(N<K)return 0;
  if(K==0)return 1;
  if(N==0)return 0;

  ll den=1;
  for(ll i=1;i<=K;i++)den*=i;
  ll num=1;
  while(K--){
    num*=N;
    if(num%den==0){
      num/=den;
      den=1;
    }
    N--;
  }

  return num;
}
*/
ll n;
vl g[2 * MAX];
ll ST[8 * MAX], A[2 * MAX];
ll a[2 * MAX];
map<ll, ll> M;
ll ans[2 * MAX];
set<ll> bigF[2 * MAX];

void build(ll node, ll lo, ll hi) {
  if (lo == hi) {
    ST[node] = A[lo];
    return;
  }
  ll mid = (lo + hi) >> 1;
  build(node << 1, lo, mid);
  build(node << 1 | 1, mid + 1, hi);
  ST[node] = ST[node << 1] + ST[node << 1 | 1];
}

void update(ll node, ll lo, ll hi, ll x, ll y) {
  if (lo == hi) {
    ST[node] += y;
    return;
  }
  ll mid = (lo + hi) >> 1;
  if (lo <= x and mid >= x) {
    update(node << 1, lo, mid, x, y);
  } else {
    update(node << 1 | 1, mid + 1, hi, x, y);
  }
  ST[node] = max(ST[node << 1], ST[node << 1 | 1]);
}

ll query(ll node, ll lo, ll hi, ll l, ll r) {
  if (lo > r or hi < l) {
    return 0;
  } else if (l <= lo and hi <= r) {
    return ST[node];
  }
  ll mid = (lo + hi) >> 1LL;
  ll p1 = query(node << 1, lo, mid, l, r);
  ll p2 = query(node << 1 | 1, mid + 1, hi, l, r);
  return max(p1, p2);
}

ll dfs(ll u, ll p) {
  // cout<<u<<'\\n';
  // for(ll i=1;i<=n;++i){
  //   cout<<query(1,1,n,i,i)<<' ';
  // }
  // cout<<'\\n';
  ll pos = M[a[u]];
  ll mx = query(1, 1, n, 1, pos - 1);
  // cout<<" RANGE , ANS "<<1<<' '<<pos-1<<' '<<mx<<'\\n';
  ans[u] = mx + 1;
  bigF[pos].insert(ans[u]);
  ll onspo = query(1, 1, n, pos, pos);
  update(1, 1, n, pos, -onspo + (*bigF[pos].rbegin()));
  for (auto v : g[u]) {
    if (v != p) {
      dfs(v, u);
    }
  }
  bigF[pos].erase(ans[u]);
  onspo = query(1, 1, n, pos, pos);
  if (bigF[pos].empty()) {
    update(1, 1, n, pos, -onspo);
  } else {
    update(1, 1, n, pos, -onspo + (*bigF[pos].rbegin()));
  }
}

int main() {
  FAST;
  cin >> n;
  for (ll i = 1; i <= n; ++i) {
    cin >> a[i];
    M[a[i]];
  }
  ll cur = 1;
  for (auto &it : M) {
    it.second = cur++;
  }
  for (ll i = 1; i <= n - 1; ++i) {
    ll u, v;
    cin >> u >> v;
    g[u].pb(v);
    g[v].pb(u);
  }
  dfs(1, 0);
  for (ll i = 1; i <= n; ++i)
    cout << ans[i] << '\\n';
  return 0;
}

/*
 WA? check edge cases, N=1,M=1 etc. Read code fully once and check all
 variables. Read the question again and see what you might have missed. Consider
 changing your solution or find more cases.
 */