zoukankan      html  css  js  c++  java
  • [洛谷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;
    } 
    

      

  • 相关阅读:
    fread 和 read的区别
    Windows下的linux开发环境Cygwin的安装配置
    开机出现grub提示符后怎样进入系统?
    Matlab中函数句柄的优点
    UNIX环境高级编程的apue.h源码APUE
    装了一个ubuntu10.10,打印机不能添加了,
    迅雷上如何下载热映的电影大片~~
    我的linux 初始配置安装的东东,最好保存上一份,对于经常装linux的朋友
    HDU 1875 畅通工程再续
    HDU 1874 畅通工程续
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10339451.html
Copyright © 2011-2022 走看看