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

#include <bits/stdc++.h>
using namespace std;
#define IOS                                                                    \\
  ios::sync_with_stdio(0);                                                     \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define endl "\\n"
#define ll long long
#define int long long
#define double long double
#define max(a, b) (a > b ? a : b)
#define min(a, b) (a < b ? a : b)
#define mp make_pair
#define pb push_back
#define inf INT_MAX
#define f first
#define s second
#define all(v) v.begin(), v.end()
#define INF INT_MAX
const int N = 200005;
vector<vector<int>> g;
vector<bool> vis;
vector<int> node;
vector<int> ans;
multiset<int> ss;

// LIS on tree
// O(N Log N) solution

void dfs(int s, int ps) {

  auto it = ss.lower_bound(node[s]);
  int y = -1;
  ss.insert(node[s]);
  if (it != ss.end()) {
    y = *it;
    ss.erase(it);
  }

  ans[s] = ss.size();
  for (auto &i : g[s]) {
    if (i == ps)
      continue;

    dfs(i, s);
  }

  auto it1 = ss.find(node[s]);
  if (it1 != ss.end())
    ss.erase(it1); // to delete vertices not in current path

  if (y != -1)
    ss.insert(y); // to restore LIS
}

int32_t main() {
  /*#ifndef ONLINE_JUDGE
     freopen("in.txt","r",stdin);
     freopen("out.txt","w",stdout);
  #endif*/
  IOS int n, u, v;
  cin >> n;
  g.resize(n + 1);
  node.resize(n + 1, 0);
  ans.resize(n + 1, 0);
  for (int i = 1; i <= n; i++)
    cin >> node[i];
  for (int i = 1; i <= n - 1; i++) {
    cin >> u >> v;
    g[u].pb(v);
    g[v].pb(u);
  }

  vis.resize(n + 1, false);
  dfs(1, 0);
  for (int i = 1; i <= n; i++) {
    cout << ans[i] << endl;
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define IOS                                                                    \\
  ios::sync_with_stdio(0);                                                     \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define endl "\\n"
#define ll long long
#define int long long
#define double long double
#define max(a, b) (a > b ? a : b)
#define min(a, b) (a < b ? a : b)
#define mp make_pair
#define pb push_back
#define inf INT_MAX
#define f first
#define s second
#define all(v) v.begin(), v.end()
#define INF INT_MAX
const int N = 200005;
vector<int> g[N];
vector<bool> vis;
vector<int> node;
vector<int> path, par;
// LIS on tree

//  bool found;
//   void dfs(int s,int des,vector<int>& path)
//   {
//     path.push_back(s);
//     //cout<<path.size()<<" ";
//     if(s==des)
//       {found=true; return;}
//     if(vis[s]) return;
//       vis[s] = true;

//       int flag = 0;
//        if(g[s].size()!=0) {
//         for (int j = 0; j < g[s].size(); j++) {
//             // if the node is not visited
//             if (vis[g[s][j]] == false) {
//                 dfs(g[s][j],des,path);
//                 if(found)return;    flag = 1;
//             }
//         }
//     }
//     if (flag == 0) {
//           path.pop_back();
//     }

// }

void bfs(int s) {
  int k, i;
  queue<int> q;
  vis[s] = true;
  q.push(s);
  while (!q.empty()) {
    k = q.front();
    // cout<<k<<" "<<endl;
    q.pop();
    for (i = 0; i < g[k].size(); i++) {
      if (!vis[g[k][i]]) {
        par[g[k][i]] = k;
        q.push(g[k][i]);
        vis[g[k][i]] = true;
      }
    }
  }
}

int LIS(vector<int> v) {
  int n = v.size();
  if (v.size() == 0 or v.size() == 1)
    return 1;
  vector<int> T(n + 1), R(n + 1, -1);
  int len = 0;
  T[0] = 0;

  for (int i = 1; i < n; i++) {
    if (v[i] > v[T[len]]) {
      len++;
      T[len] = i;
      R[T[len]] = T[len - 1];

    } else if (v[i] < v[T[0]]) {
      T[0] = i;

    } else {
      // binary search and insert that value as per its ceiling till now
      // int low=ceilIndex(v,T,len,v[i]);
      int low = 0, high = len;
      while (low <= high) {
        int mid = (low + high) / 2;
        if (v[T[mid]] > v[i])
          high = mid - 1;
        else
          low = mid + 1;
      }
      T[low] = i;
      R[T[low]] = T[low - 1];
    }
  }
  return len + 1;
}

int32_t main() {
  // #ifndef ONLINE_JUDGE
  //    freopen("in.txt","r",stdin);
  //    freopen("out.txt","w",stdout);
  // #endif
  IOS int n, u, v;
  cin >> n;
  par.resize(n + 1, 0);
  node.resize(n + 1, 0);
  for (int i = 1; i <= n; i++)
    cin >> node[i];
  for (int i = 1; i <= n - 1; i++) {
    cin >> u >> v;
    g[u].pb(v);
    g[v].pb(u);
  }
  // for (int i = 1; i <=n; ++i)
  // {
  //   cout<<i<<": ";
  //   for (int j = 0; j < g[i].size(); ++j)
  //   {
  //     /* code
  //     cout<<g[i][j]<<" ";
  //   }
  //   cout<<"\\n";
  //   /* code */
  // }*/
  vis.resize(n + 1, false);
  bfs(1);
  for (int i = 1; i <= n; i++) {
    vector<int> ans;

    int d = i;
    ans.pb(node[d]);
    while (d != 1) {
      ans.pb(node[par[d]]);
      d = par[d];
    }
    reverse(ans.begin(), ans.end());
    // cout<<i<<" "<<ans.size()<<endl;

    // for(auto i:ans)
    //   cout<<i<<"   ";

    //  cout<<endl;

    cout << LIS(ans) << endl;
    // cout<<endl<<endl;
  }

  return 0;
}