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

#include <algorithm> // other
#include <bitset>
#include <cassert> // c
#include <complex>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream> // io
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <vector> // container
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define ALL(c) c.begin(), c.end()
#define REP(i, n) FOR(i, 0, n)
#define REPr(i, n) FORr(i, 0, n)
#define FOR(i, l, r) for (int i = (int)(l); i < (int)(r); ++i)
#define FORr(i, l, r) for (int i = (int)(r)-1; i >= (int)(l); --i)
#define EACH(it, o) for (auto it = (o).begin(); it != (o).end(); ++it)
#define IN(l, v, r) ((l) <= (v) && (v) < (r))
#define UNIQUE(v) v.erase(unique(ALL(v)), v.end())
// debug
#define DUMP(x) cerr << #x << " = " << (x)
#define LINE() cerr << " (L" << __LINE__ << ")"

class range {
private:
  struct Iter {
    int v;
    int operator*() { return v; }
    bool operator!=(Iter &itr) { return v < itr.v; }
    void operator++() { ++v; }
  };
  Iter i, n;

public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iter &begin() { return i; }
  Iter &end() { return n; }
};

// input
template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
  return is >> p.first >> p.second;
}
template <typename T1> istream &operator>>(istream &is, tuple<T1> &t) {
  return is >> get<0>(t);
}
template <typename T1, typename T2>
istream &operator>>(istream &is, tuple<T1, T2> &t) {
  return is >> get<0>(t) >> get<1>(t);
}
template <typename T1, typename T2, typename T3>
istream &operator>>(istream &is, tuple<T1, T2, T3> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t);
}
template <typename T1, typename T2, typename T3, typename T4>
istream &operator>>(istream &is, tuple<T1, T2, T3, T4> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
istream &operator>>(istream &is, const tuple<T1, T2, T3, T4, T5> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t) >> get<4>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6>
istream &operator>>(istream &is, const tuple<T1, T2, T3, T4, T5, T6> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t) >> get<4>(t) >>
         get<5>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7>
istream &operator>>(istream &is, const tuple<T1, T2, T3, T4, T5, T6, T7> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t) >> get<4>(t) >>
         get<5>(t) >> get<6>(t);
}
template <typename T> istream &operator>>(istream &is, vector<T> &as) {
  for (int i : range(as.size()))
    is >> as[i];
  return is;
}

// output
template <typename T> ostream &operator<<(ostream &os, const set<T> &ss) {
  for (auto a : ss) {
    if (a != ss.begin())
      os << " ";
    os << a;
  }
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << p.first << " " << p.second;
}
template <typename K, typename V>
ostream &operator<<(ostream &os, const map<K, V> &m) {
  bool isF = true;
  for (auto &p : m) {
    if (!isF)
      os << endl;
    os << p;
    isF = false;
  }
  return os;
}
template <typename T1> ostream &operator<<(ostream &os, const tuple<T1> &t) {
  return os << get<0>(t);
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const tuple<T1, T2> &t) {
  return os << get<0>(t) << " " << get<1>(t);
}
template <typename T1, typename T2, typename T3>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t);
}
template <typename T1, typename T2, typename T3, typename T4>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t) << " " << get<4>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t) << " " << get<4>(t) << " " << get<5>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6, T7> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t) << " " << get<4>(t) << " " << get<5>(t) << " "
            << get<6>(t);
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &as) {
  for (int i : range(as.size())) {
    if (i != 0)
      os << " ";
    os << as[i];
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &as) {
  for (int i : range(as.size())) {
    if (i != 0)
      os << endl;
    os << as[i];
  }
  return os;
}

// values
template <typename T> inline T INF() { assert(false); };
template <> inline int INF<int>() { return 1 << 28; };
template <> inline ll INF<ll>() { return 1LL << 58; };
template <> inline double INF<double>() { return 1e16; };
template <> inline long double INF<long double>() { return 1e16; };

template <class T> inline T EPS() { assert(false); };
template <> inline int EPS<int>() { return 1; };
template <> inline ll EPS<ll>() { return 1LL; };
template <> inline double EPS<double>() { return 1e-8; };
template <> inline long double EPS<long double>() { return 1e-8; };

// min{2^r | n < 2^r}
template <typename T> T upper_pow2(T n) {
  T res = 1;
  while (res < n)
    res <<= 1;
  return res;
}
// max{d | 2^d  <= n}
template <typename T> T msb(T n) {
  int d = 30;
  while ((1 << d) > n)
    d--;
  return d;
}

template <typename T, typename U> T pmod(T v, U M) { return (v % M + M) % M; }

struct UnionFind {
  vector<int> par, rank, ss;
  int size;
  UnionFind(int n) {
    REP(i, n) par.push_back(i);
    rank = vector<int>(n);
    ss = vector<int>(n, 1);
    size = n;
  }
  int root(int x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  bool same(int x, int y) { return root(x) == root(y); }
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (rank[x] > rank[y])
      swap(x, y);
    par[x] = y;
    ss[y] += ss[x];
    if (rank[x] == rank[y])
      rank[x]++;
    size--;
  }
  int getS(int x) { return ss[root(x)]; }
};

typedef vector<vector<int>> Graph;
class TarjanLCA {
public:
  Graph &g;
  vector<tuple<int, int, int>> &qs;
  UnionFind uf;
  vector<int> ancestor;
  vector<bool> passed;
  vector<vector<int>> uquery;
  TarjanLCA(Graph &g, int r, vector<tuple<int, int, int>> &qs)
      : g(g), qs(qs), uf(UnionFind(g.size())) {
    passed = vector<bool>(g.size());
    ancestor = vector<int>(g.size());
    uquery = vector<vector<int>>(g.size());
    for (int i : range(qs.size())) {
      int u, v, res;
      tie(u, v, res) = qs[i];
      uquery[u].push_back(i);
      uquery[v].push_back(i);
    }
    visit(-1, r);
  };
  void visit(int p, int s) {
    ancestor[uf.root(s)] = s;
    for (int t : g[s])
      if (t != p) {
        visit(s, t);
        uf.unite(s, t);
        ancestor[uf.root(s)] = s;
      }
    passed[s] = true;
    for (int i : uquery[s]) {
      int u, v, res;
      tie(u, v, res) = qs[i];
      int w = (u == s ? v : v == s ? u : -1);
      if (w >= 0 && passed[w])
        get<2>(qs[i]) = ancestor[uf.root(w)];
    }
  }
};

class Main {
public:
  void run() {
    int n;
    cin >> n;
    Graph g(n);
    REP(i, n) {
      int k;
      cin >> k;
      REP(j, k) {
        int t;
        cin >> t;
        g[i].push_back(t);
        g[t].push_back(i);
      }
    }
    int q;
    cin >> q;
    vector<tuple<int, int, int>> qs(q);
    REP(i, q) {
      int u, v;
      cin >> u >> v;
      qs[i] = make_tuple(u, v, -1);
    }

    TarjanLCA lca(g, 0, qs);
    REP(i, q) cout << get<2>(qs[i]) << endl;
  }
};

int main() {
  cout << fixed << setprecision(20);
  cin.tie(0);
  ios::sync_with_stdio(false);
  Main().run();
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm> // other
#include <bitset>
#include <cassert> // c
#include <complex>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream> // io
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <vector> // container
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define ALL(c) c.begin(), c.end()
#define REP(i, n) FOR(i, 0, n)
#define REPr(i, n) FORr(i, 0, n)
#define FOR(i, l, r) for (int i = (int)(l); i < (int)(r); ++i)
#define FORr(i, l, r) for (int i = (int)(r)-1; i >= (int)(l); --i)
#define EACH(it, o) for (auto it = (o).begin(); it != (o).end(); ++it)
#define IN(l, v, r) ((l) <= (v) && (v) < (r))
#define UNIQUE(v) v.erase(unique(ALL(v)), v.end())
// debug
#define DUMP(x) cerr << #x << " = " << (x)
#define LINE() cerr << " (L" << __LINE__ << ")"

class range {
private:
  struct Iter {
    int v;
    int operator*() { return v; }
    bool operator!=(Iter &itr) { return v < itr.v; }
    void operator++() { ++v; }
  };
  Iter i, n;

public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iter &begin() { return i; }
  Iter &end() { return n; }
};

// input
template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
  return is >> p.first >> p.second;
}
template <typename T1> istream &operator>>(istream &is, tuple<T1> &t) {
  return is >> get<0>(t);
}
template <typename T1, typename T2>
istream &operator>>(istream &is, tuple<T1, T2> &t) {
  return is >> get<0>(t) >> get<1>(t);
}
template <typename T1, typename T2, typename T3>
istream &operator>>(istream &is, tuple<T1, T2, T3> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t);
}
template <typename T1, typename T2, typename T3, typename T4>
istream &operator>>(istream &is, tuple<T1, T2, T3, T4> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
istream &operator>>(istream &is, const tuple<T1, T2, T3, T4, T5> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t) >> get<4>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6>
istream &operator>>(istream &is, const tuple<T1, T2, T3, T4, T5, T6> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t) >> get<4>(t) >>
         get<5>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7>
istream &operator>>(istream &is, const tuple<T1, T2, T3, T4, T5, T6, T7> &t) {
  return is >> get<0>(t) >> get<1>(t) >> get<2>(t) >> get<3>(t) >> get<4>(t) >>
         get<5>(t) >> get<6>(t);
}
template <typename T> istream &operator>>(istream &is, vector<T> &as) {
  for (int i : range(as.size()))
    is >> as[i];
  return is;
}

// output
template <typename T> ostream &operator<<(ostream &os, const set<T> &ss) {
  for (auto a : ss) {
    if (a != ss.begin())
      os << " ";
    os << a;
  }
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << p.first << " " << p.second;
}
template <typename K, typename V>
ostream &operator<<(ostream &os, const map<K, V> &m) {
  bool isF = true;
  for (auto &p : m) {
    if (!isF)
      os << endl;
    os << p;
    isF = false;
  }
  return os;
}
template <typename T1> ostream &operator<<(ostream &os, const tuple<T1> &t) {
  return os << get<0>(t);
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const tuple<T1, T2> &t) {
  return os << get<0>(t) << " " << get<1>(t);
}
template <typename T1, typename T2, typename T3>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t);
}
template <typename T1, typename T2, typename T3, typename T4>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t) << " " << get<4>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t) << " " << get<4>(t) << " " << get<5>(t);
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
          typename T6, typename T7>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3, T4, T5, T6, T7> &t) {
  return os << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " "
            << get<3>(t) << " " << get<4>(t) << " " << get<5>(t) << " "
            << get<6>(t);
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &as) {
  for (int i : range(as.size())) {
    if (i != 0)
      os << " ";
    os << as[i];
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &as) {
  for (int i : range(as.size())) {
    if (i != 0)
      os << endl;
    os << as[i];
  }
  return os;
}

// values
template <typename T> inline T INF() { assert(false); };
template <> inline int INF<int>() { return 1 << 28; };
template <> inline ll INF<ll>() { return 1LL << 58; };
template <> inline double INF<double>() { return 1e16; };
template <> inline long double INF<long double>() { return 1e16; };

template <class T> inline T EPS() { assert(false); };
template <> inline int EPS<int>() { return 1; };
template <> inline ll EPS<ll>() { return 1LL; };
template <> inline double EPS<double>() { return 1e-8; };
template <> inline long double EPS<long double>() { return 1e-8; };

// min{2^r | n < 2^r}
template <typename T> T upper_pow2(T n) {
  T res = 1;
  while (res < n)
    res <<= 1;
  return res;
}
// max{d | 2^d  <= n}
template <typename T> T msb(T n) {
  int d = 30;
  while ((1 << d) > n)
    d--;
  return d;
}

template <typename T, typename U> T pmod(T v, U M) { return (v % M + M) % M; }

struct UnionFind {
  vector<int> par, rank, ss;
  int size;
  UnionFind(int n) {
    REP(i, n) par.push_back(i);
    rank = vector<int>(n);
    ss = vector<int>(n, 1);
    size = n;
  }
  int root(int x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  bool same(int x, int y) { return root(x) == root(y); }
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    if (rank[x] > rank[y])
      swap(x, y);
    par[x] = y;
    ss[y] += ss[x];
    if (rank[x] == rank[y])
      rank[x]++;
    size--;
  }
  int getS(int x) { return ss[root(x)]; }
};

typedef vector<vector<int>> Graph;
class TarjanLCA {
public:
  Graph &g;
  UnionFind uf;

  vector<int> ancestor;
  vector<bool> passed;

  TarjanLCA(Graph &g) : g(g), uf(UnionFind(g.size())) {
    passed = vector<bool>(g.size());
    ancestor = vector<int>(g.size());
  };
  void visit(int p, int s, vector<tuple<int, int, int>> &qs) {
    ancestor[uf.root(s)] = s;
    for (int t : g[s])
      if (t != p) {
        visit(s, t, qs);
        uf.unite(s, t);
        ancestor[uf.root(s)] = s;
      }
    passed[s] = true;
    for (auto &q : qs) {
      int w = (get<1>(q) == s ? get<0>(q) : get<0>(q) == s ? get<1>(q) : -1);
      if (w >= 0 && passed[w]) {
        get<2>(q) = ancestor[uf.root(w)];
      }
    }
  }
  void leastCommonAncestor(int r, vector<tuple<int, int, int>> &qs) {
    visit(-1, r, qs);
  }
};

class Main {
public:
  void run() {
    int n;
    cin >> n;
    Graph g(n);
    REP(i, n) {
      int k;
      cin >> k;
      REP(j, k) {
        int t;
        cin >> t;
        g[i].push_back(t);
        g[t].push_back(i);
      }
    }
    TarjanLCA lca(g);
    int q;
    cin >> q;
    vector<tuple<int, int, int>> qs(q);
    REP(i, q) {
      int u, v;
      cin >> u >> v;
      qs[i] = make_tuple(u, v, -1);
    }
    lca.leastCommonAncestor(0, qs);

    REP(i, q) { cout << get<2>(qs[i]) << endl; }
  }
};

int main() {
  cout << fixed << setprecision(20);
  cin.tie(0);
  ios::sync_with_stdio(false);
  Main().run();
  return 0;
}