[洛谷P3398]仓鼠找sugar

题目大意:给你一棵$n(nleqslant10^5)$个点的树,$m(mleqslant10^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 = '
';
	}
	#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;
} 

  

原文地址:https://www.cnblogs.com/Memory-of-winter/p/10339451.html