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

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <typeinfo>
#include <vector>
#define syosu(x) fixed << setprecision(x)
using namespace std;
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<double, double> pdd;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<P> vp;
typedef vector<bool> vb;
typedef vector<vp> vvp;
typedef pair<int, P> pip;
typedef vector<pip> vip;
const int inf = 1 << 30;
const double pi = acos(-1);
const double eps = 1e-8;
const vi emp;

class RMQ {
private:
  vp rmq;
  void updatefunc(int x, int k, int num) {
    rmq[x].first = rmq[k].first;
    rmq[x].second = num;
  }

public:
  int n;
  void init(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    rmq = vp(2 * n - 1, P(inf, -1));
  }
  void update(int k, int x) {
    k += n - 1;
    rmq[k].second = k - n + 1;
    rmq[k].first = x;
    while (k > 0) {
      k = (k - 1) / 2;
      if (rmq[k * 2 + 1].first < rmq[k * 2 + 2].first) {
        updatefunc(k, k * 2 + 1, rmq[k * 2 + 1].second);
      } else if (rmq[k * 2 + 1].first > rmq[k * 2 + 2].first) {
        updatefunc(k, k * 2 + 2, rmq[k * 2 + 2].second);
      } else {
        updatefunc(k, k * 2 + 1, rmq[k * 2 + 1].second);
        updatefunc(k, k * 2 + 2, rmq[k * 2 + 2].second);
      }
    }
  }
  P query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return P(inf, -1);
    if (a <= l && r <= b)
      return rmq[k];
    else {
      int mid = (l + r) / 2;
      P vl = query(a, b, k * 2 + 1, l, mid);
      P vr = query(a, b, k * 2 + 2, mid, r);
      return (vl.first < vr.first) ? vl : vr;
    }
  }
  void open() {
    for (int i = 0; i < rmq.size(); i++)
      cout << rmq[i].first << endl;
    for (int i = 0; i < rmq.size(); i++)
      cout << rmq[i].second << endl;
  }
};

class Graph {
private:
  int GV;
  vvi List;
  void Euler(int x, int l, int &ind, vb &used) {
    euler[ind] = x;
    level.update(ind, l);
    used[x] = 1;
    if (disc[x] == -1)
      disc[x] = ind;
    ind++;
    for (int i = 0; i < List[x].size(); i++) {
      int v = List[x][i];
      if (!used[v]) {
        Euler(v, l + 1, ind, used);
        euler[ind] = x;
        level.update(ind, l);
        ind++;
      }
    }
  }

public:
  vi euler, disc;
  RMQ level;
  Graph(int v) {
    GV = v;
    List = vvi(v);
  }
  void add_edge(int x, int y) {
    List[x].push_back(y);
    List[y].push_back(x);
  }
  void LCAprepare() {
    euler = vi(2 * GV - 1);
    disc = vi(GV, -1);
    level.init(2 * GV - 1);
    int ind = 0;
    vb used(GV);
    Euler(0, 0, ind, used);
  }
  int LCA(int s, int t) {
    s = disc[s];
    t = disc[t];
    if (s > t)
      swap(s, t);
    P index = level.query(s, t + 1, 0, 0, level.n);
    return euler[index.second];
  }
};

int V, Q;

int main() {
  cin >> V;
  Graph gra(V);
  int n, s;
  for (int i = 0; i < V; i++) {
    cin >> n;
    for (int j = 0; j < n; j++) {
      cin >> s;
      gra.add_edge(i, s);
    }
  }
  gra.LCAprepare();
  cin >> Q;
  int u, v;
  for (int i = 0; i < Q; i++) {
    cin >> u >> v;
    cout << gra.LCA(u, v) << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <typeinfo>
#include <vector>
#define syosu(x) fixed << setprecision(x)
using namespace std;
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<double, double> pdd;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<P> vp;
typedef vector<bool> vb;
typedef vector<vp> vvp;
typedef pair<int, P> pip;
typedef vector<pip> vip;
const int inf = 1 << 30;
const double pi = acos(-1);
const double eps = 1e-8;
const vi emp;

class RMQ {
private:
  vector<pair<int, vi>> rmq;
  void updatefunc(int x, int k, vi num) {
    rmq[x].first = rmq[k].first;
    for (int i = 0; i < num.size(); i++) {
      rmq[x].second.push_back(num[i]);
    }
  }

public:
  int n;
  void init(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    rmq = vector<pair<int, vi>>(2 * n - 1, pair<int, vi>(inf, emp));
  }
  void update(int k, int x) {
    k += n - 1;
    if (rmq[k].second.empty())
      rmq[k].second.push_back(k - n + 1);
    rmq[k].first = x;
    while (k > 0) {
      k = (k - 1) / 2;
      rmq[k].second.clear();
      if (rmq[k * 2 + 1].first < rmq[k * 2 + 2].first) {
        updatefunc(k, k * 2 + 1, rmq[k * 2 + 1].second);
      } else if (rmq[k * 2 + 1].first > rmq[k * 2 + 2].first) {
        updatefunc(k, k * 2 + 2, rmq[k * 2 + 2].second);
      } else {
        updatefunc(k, k * 2 + 1, rmq[k * 2 + 1].second);
        updatefunc(k, k * 2 + 2, rmq[k * 2 + 2].second);
      }
    }
  }
  pair<int, vi> query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return pair<int, vi>(inf, emp);
    if (a <= l && r <= b)
      return rmq[k];
    else {
      int mid = (l + r) / 2;
      pair<int, vi> vl = query(a, b, k * 2 + 1, l, mid);
      pair<int, vi> vr = query(a, b, k * 2 + 2, mid, r);
      return (vl.first < vr.first) ? vl : vr;
    }
  }
  int open(int x) {
    x += n - 1;
    return rmq[x].first;
  }
  void full_open() {
    for (int i = 0; i < rmq.size(); i++) {
      for (int j = 0; j < rmq[i].second.size(); j++) {
        cout << rmq[i].second[j] << ' ';
      }
      cout << endl;
    }
  }
};

class Graph {
private:
  int GV;
  vvi List;
  void Euler(int x, int l, int &ind, vb &used) {
    euler[ind] = x;
    level.update(ind, l);
    used[x] = 1;
    if (disc[x] == -1)
      disc[x] = ind;
    ind++;
    for (int i = 0; i < List[x].size(); i++) {
      int v = List[x][i];
      if (!used[v]) {
        Euler(v, l + 1, ind, used);
        euler[ind] = x;
        level.update(ind, l);
        ind++;
      }
    }
  }

public:
  vi euler, disc;
  RMQ level;
  Graph(int v) {
    GV = v;
    List = vvi(v);
  }
  void add_edge(int x, int y) {
    List[x].push_back(y);
    List[y].push_back(x);
  }
  void LCAprepare() {
    euler = vi(2 * GV - 1);
    disc = vi(GV, -1);
    level.init(2 * GV - 1);
    int ind = 0;
    vb used(GV);
    Euler(0, 0, ind, used);
  }
  int LCA(int s, int t) {
    s = disc[s];
    t = disc[t];
    if (s > t)
      swap(s, t);
    pair<int, vi> index = level.query(s, t + 1, 0, 0, level.n);
    return euler[index.second[0]];
  }
};

int V, Q;

int main() {
  cin >> V;
  Graph gra(V);
  int n, s;
  for (int i = 0; i < V; i++) {
    cin >> n;
    for (int j = 0; j < n; j++) {
      cin >> s;
      gra.add_edge(i, s);
    }
  }
  gra.LCAprepare();
  cin >> Q;
  int u, v;
  for (int i = 0; i < Q; i++) {
    cin >> u >> v;
    cout << gra.LCA(u, v) << endl;
  }
}