[洛谷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;
}

浙公网安备 33010602011771号