Live2D

P3398 仓鼠找sugar 又一次血的教训

做什么题都要注意数组的大小,不要犯下数组越界的错误(温馨(狠心)提示);

做了好多遍就是不对,原来是【20】的数组,在for下循环1——》20,神奇爆零;

链接:https://www.luogu.org/problemnew/show/P3398

这道题有一个性质:

判断树上两条路径是否有交点或重叠部分,那就是

有a,b一条路径,还有c,d这条路径。

要是这两条路径相交或重合,

那么要不是lca(a,b)在cd上,就是lca(c,d)在ab上;

显然易得啊(反正我是不会证明,背下来记好了);

 

倍增lca

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=2000050;
int pre[maxn],other[maxn],last[maxn],l;
int n,q;
void add(int x,int y)
{
    l++;
    pre[l]=last[x];
    last[x]=l;
    other[l]=y;
}
int dep[maxn],jump[maxn][20];
void dfs(int u)
{
    for(int p=last[u];p;p=pre[p])
    {
        int v=other[p];
        if(v==jump[u][0]) continue;
        dep[v]=dep[u]+1;
        jump[v][0]=u;
        dfs(v);
    }
}

int lca(int u,int v)
{
    if(dep[u]<dep[v]) swap(u,v);
    for(int i=0;i<=17;i++)
    {
        if((dep[u]-dep[v])&(1<<i)) u=jump[u][i];
    }
    if(u==v) return u;
    for(int j=17;j>=0;j--)
    {
        if(jump[u][j]!=jump[v][j])
        {
            u=jump[u][j];
            v=jump[v][j];
        }
    }
    return jump[u][0];
}
int main()
{
    scanf("%d%d",&n,&q);
    for(int i=1;i<n;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b);
        add(b,a);
    }
    dfs(1);
    for(int j=1;j<=17;j++)//17就够了,不要搞什么20 
    {
        for(int i=1;i<=n;i++)
        {
            jump[i][j]=jump[jump[i][j-1]][j-1];
        }
    }
    for(int i=1;i<=q;i++)
    {
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        int x=lca(a,b);
        int y=lca(c,d);
        int l1=dep[a]+dep[b]-2*dep[x];//a->b路径长度 
        int l2=dep[c]+dep[d]-2*dep[y];//c->d路径长度 
        if(dep[c]+dep[x]-2*dep[lca(x,c)]+dep[d]+dep[x]-2*dep[lca(x,d)]==l2)//c->x->d==l2
        {
            printf("Y\n");
            continue;
        }
            if(dep[a]+dep[y]-2*dep[lca(a,y)]+dep[b]+dep[y]-2*dep[lca(y,b)]==l1)//a->y->b==l1,就是两条线段长度和等于整个线段长度 
        {
            printf("Y\n");
            continue;
        }
        printf("N\n");
    }
    return 0;
}

 

posted @ 2019-06-21 16:54  世界光明  阅读(272)  评论(0编辑  收藏  举报