[洛谷P3398]仓鼠找sugar
题目大意:给你一棵$n(n\leqslant10^5)$个点的树,$m(m\leqslant10^5)$次询问,每次询问路径$a->b$和路径$c->d$是否有交点
题解:经过观察发现若有交点,在$LCA_{a,b}$或$LCA_{c,d}$一定有交,判断一下即可
卡点:无
C++ Code:
#include <cstdio> #include <algorithm> #include <cstring> #define maxn 100005 #include <cctype> namespace R { #define M 1 << 23 int x; char op[M], *ch = op - 1; inline void init() { fread(op, 1, M, stdin); } int read() { while (isspace(*++ch)) ; for (x = *ch & 15; isdigit(*++ch); ) x = x * 10 + (*ch & 15); return x; } #undef M } namespace W { #define M 1 << 19 char op[M], *ch = op - 1; inline void end() { fwrite(op, 1, ch - op, stdout); } inline void put(const char __ch) { *++ch = __ch; *++ch = '\n'; } #undef M } using R::read; using W::put; int n, m; int head[maxn], cnt; struct Edge { int to, nxt; } e[maxn << 1]; inline void addedge(const int a, const int b) { e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt; e[++cnt] = (Edge) {a, head[b]}; head[b] = cnt; } #define M 18 int fa[maxn][M], dep[maxn]; void dfs(const int u) { for (register int i = 1; i < M; i++) fa[u][i] = fa[fa[u][i - 1]][i - 1]; for (register int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if (v != *fa[u]) { *fa[v] = u; dep[v] = dep[u] + 1; dfs(v); } } } inline int LCA(int x, int y) { if (x == y) return x; if (dep[x] < dep[y]) std::swap(x, y); for (register int i = dep[x] - dep[y]; i; i &= i - 1) x = fa[x][__builtin_ctz(i)]; if (x == y) return x; for (register int i = M - 1; ~i; i--) if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i]; return *fa[x]; } #undef M #define PutRe(x) {put(x); return ;} void solve(const int x1, const int y1, const int x2, const int y2) { int lca_1 = LCA(x1, y1), lca_2 = LCA(x2, y2); if (lca_1 == lca_2) PutRe('Y') if (dep[lca_1] == dep[lca_2]) PutRe('N') if (dep[lca_1] > dep[lca_2]) { if (dep[lca_1] <= dep[x2]) if (LCA(x2, lca_1) == lca_1) PutRe('Y') if (dep[lca_1] <= dep[y2]) if (LCA(y2, lca_1) == lca_1) PutRe('Y') PutRe('N'); } else { if (dep[lca_2] <= dep[x1]) if (LCA(x1, lca_2) == lca_2) PutRe('Y') if (dep[lca_2] <= dep[y1]) if (LCA(y1, lca_2) == lca_2) PutRe('Y') PutRe('N'); } } int main() { R::init(); n = read(), m = read(); for (register int i = 1, a, b; i < n; i++) { a = read(), b = read(); addedge(a, b); } dep[1] = 0; dfs(1); for (register int i = 1, x1, y1, x2, y2; i <= m; i++) { x1 = read(), y1 = read(), x2 = read(), y2 = read(); solve(x1, y1, x2, y2); } W::end(); return 0; }