Language: C++

#include <cassert>
#include <cstdint>
#include <utility>
#include <vector>

class UnionFind {

public:
	using size_type = std::uint_fast32_t;

private:
	std::vector<std::pair<bool, size_type>> tree;

public:
	UnionFind(const size_type size) : tree(size, std::make_pair(1, 1)) {}
	size_type find(const size_type x) {
		assert(x < size());
		if (tree[x].first)
			return x;
		return tree[x].second = find(tree[x].second);
	}
	bool unite(size_type x, size_type y) {
		assert(x < size());
		assert(y < size());
		x = find(x);
		y = find(y);
		if (x == y)
			return false;
		if (tree[x].second < tree[y].second)
			std::swap(x, y);
		tree[x].second += tree[y].second;
		tree[y] = std::make_pair(0, x);
		return true;
	}
	bool same(const size_type x, const size_type y) {
		assert(x < size());
		assert(y < size());
		return find(x) == find(y);
	}
	size_type size(const size_type x) {
		assert(x < size());
		return tree[find(x)].second;
	}
	size_type size() const noexcept { return tree.size(); }
	bool empty() const noexcept { return tree.empty(); }
};

#include <cstddef>
#include <functional>
#include <utility>
#include <vector>

template <class GraphContainer, class UnionFindDataStructure>
std::vector<typename GraphContainer::size_type> TarjansOfflineLCA(
	const GraphContainer &graph, const typename GraphContainer::size_type root,
	const std::vector<std::pair<typename GraphContainer::size_type,
	typename GraphContainer::size_type>> &queries) {
	using size_type = typename GraphContainer::size_type;
	const size_type size_ = graph::size();
	UnionFindDataStructure uft(size_);
	std::vector<size_type> ret(queries.size(), size_), anc(size_);
	std::vector<std::vector<std::size_t>> qset(size_);

	for (std::size_t i = 0; i < queries.size(); ++i) {
		qset[queries[i].first].emplace_back(i);
		qset[queries[i].second].emplace_back(i);
	}

	st.emplace(root, 0);

	std::function<void(const size_type, const size_type)> dfs =
		[&](const size_type v, const size_type prev) {
		anc[v] = v;
		for (const auto &&e : graph[v]) {
			if (e.to != prev) {
				dfs(e.to);
				uft.unite(v, e.to);
				anc[uft.find(v)] = v;
			}
		}
		for (const auto e : qset[v])
			if (ret[e] == size_)
				ret[e] = v;
			else
				ret[e] = anc[uft.find(ret[e])];
	};
	dfs(root, size_);
	return ret;
}


#include <cstddef>
#include <vector>

struct edge {
	using cost_type = int;
	using size_type = std::size_t;

	std::size_t to;
	edge(size_type t):to(t){}
};

template <class Edge> using Graph = std::vector<std::vector<Edge>>;

#include<cstdio>
int main() {
	using uint = unsigned int;
	uint n;
	scanf("%u", &n);
	Graph<edge> g(n);
	for (uint i = 0;i < n;++i) {
		uint k, c;
		scanf("%u", &k);
		while (k--) {
			scanf("%u", &c);
			g[i].emplace_back(c);
		}
	}
	uint q;
	scanf("%u", &q);
	using S = typename Graph<edge>::size_type;
	std::vector<std::pair<S, S>> Q;
	Q.reserve(q);
	while (q--) {
		uint u, v;
		scanf("%u%u", &u, &v);
		Q.emplace_back(u, v);
	}
	const auto &&ans=TarjansOfflineLCA<Graph<edge>, UnionFind>(g, 0, Q);
	for (const auto e : ans)
		printf("%u\n", e);
	return 0;
}


Compiler output:
a.cc: In function 'std::vector<typename GraphContainer::size_type> TarjansOfflineLCA(const GraphContainer&, typename GraphContainer::size_type, const std::vector<std::pair<typename GraphContainer::size_type, typename GraphContainer::size_type> >&)':
a.cc:59:33: error: 'graph' is not a class, namespace, or enumeration
   59 |         const size_type size_ = graph::size();
      |                                 ^~~~~
a.cc:69:9: error: 'st' was not declared in this scope; did you mean 'std'?
   69 |         st.emplace(root, 0);
      |         ^~
      |         std
a.cc: In instantiation of 'std::vector<typename GraphContainer::size_type> TarjansOfflineLCA(const GraphContainer&, typename GraphContainer::size_type, const std::vector<std::pair<typename GraphContainer::size_type, typename GraphContainer::size_type> >&) [with GraphContainer = std::vector<std::vector<edge, std::allocator<edge> >, std::allocator<std::vector<edge, std::allocator<edge> > > >; UnionFindDataStructure = UnionFind; typename GraphContainer::size_type = long unsigned int]':
a.cc:129:60:   required from here
  129 |         const auto &&ans=TarjansOfflineLCA<Graph<edge>, UnionFind>(g, 0, Q);
      |                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
a.cc:74:17: error: cannot bind rvalue reference of type 'const edge&&' to lvalue of type 'const edge'
   74 |                 for (const auto &&e : graph[v]) {
      |                 ^~~
a.cc:76:36: error: no match for call to '(std::function<void(long unsigned int, long unsigned int)>) (const std::size_t&)'
   76 |                                 dfs(e.to);
      |                                 ~~~^~~~~~
In file included from /usr/include/c++/14/functional:59,
                 from a.cc:49:
/usr/include/c++/14/bits/std_function.h:587:7: note: candidate: '_Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = void; _ArgTypes = {long unsigned int, long unsigned int}]'
  587 |       operator()(_ArgTypes... __args) const
      |       ^~~~~~~~
/usr/include/c++/14/bits/std_function.h:587:7: note:   candidate expects 2 arguments, 1 provided