zoukankan      html  css  js  c++  java
  • 【luogu P3398 仓鼠找sugar】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3398
    辣鸡树剖1300ms
    倍增大法吼啊

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn = 550000;
    const int maxlog = 20;
    int n, m, root, f[maxn][maxlog], deep[maxn];
    struct edge{
    	int next, to;
    }e[maxn<<2];
    int head[maxn], cnt;
    void add(int u, int v)
    {
    	e[++cnt].next = head[u]; e[cnt].to = v; head[u] = cnt;
    	e[++cnt].next = head[v]; e[cnt].to = u; head[v] = cnt;
    }
    void dfs(int u, int p, int d)
    {
    	f[u][0] = p;
    	deep[u] = d;
    	for(int i = head[u]; i != -1; i = e[i].next)
    	if(e[i].to != p) dfs(e[i].to, u, d+1);
    }
    void init()
    {
    	dfs(root, -1, 1);
    	for(int i = 0; i + 1 < maxlog; i++)
    	{
    		for(int u = 1; u <= n; u++)
    		if(f[u][i] < 0) f[u][i+1] = -1;
    		else f[u][i+1] = f[f[u][i]][i];
    	}
    }
    int LCA(int x, int y)
    {
    	if(deep[x] > deep[y]) swap(x,y);
    	for(int i = 0; i < maxlog; i++)
    	{
    		if(deep[x] == deep[y]) break;
    		if((deep[y]-deep[x])>>i&1) y = f[y][i];
    	}
    	if(x == y) return x;
    	for(int i = maxlog-1; i >= 0; i--)
    	{
    		if(f[x][i] != f[y][i])
    		{
    			x = f[x][i];
    			y = f[y][i];
    		}
    	}
    	return f[x][0];
    }
    int main()
    {
    	memset(head,-1,sizeof(head));
    	scanf("%d%d",&n,&m);
    	for(int i = 1; i < n; i++)
    	{
    		int u, v;
    		scanf("%d%d",&u,&v);
    		add(u,v);
    	}
    	root = 1;
    	init();
        for(int i = 1; i <= m; i++)
        {
            int a, b, c, d, p, q;
            scanf("%d%d%d%d",&a,&b,&c,&d);
            p = LCA(a,b);
            q = LCA(c,d);
            if((deep[p] > deep[c]) && (deep[p] > deep[d]))
            {
                printf("N
    ");
                continue;
            }
            if((deep[q] > deep[a]) && (deep[q] > deep[b]))		
            {
                printf("N
    ");
                continue;
            }
            if(deep[p] >= deep[q])
            {
            	if((LCA(p,c) == p) || (LCA(p,d) == p))
                {
                    printf("Y
    ");
                    continue;
                }
    		}
    		if(deep[q] >= deep[p])
            {
            	if((LCA(q,a) == q) || (LCA(q,b) == q))
                {
                    printf("Y
    ");
                    continue;
                }
    		}
            printf("N
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    unittest learning
    C++类和对象
    Linux shell基础(十二)
    Linux shell基础(十一)
    Linux shell基础(十)
    Linux shell基础(九)
    Linux shell基础(八)
    Linux shell基础(六)
    Linux shell基础(七)
    Linux shell基础(五)
  • 原文地址:https://www.cnblogs.com/MisakaAzusa/p/9222797.html
Copyright © 2011-2022 走看看