CF1304E 1-Trees and Queries

Posted chinesepikaync

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1304E 1-Trees and Queries相关的知识,希望对你有一定的参考价值。

Problem Link

(dis(u,v)) 表示 (u)(v) 在原来那棵树上的距离,可以用倍增lca (O(log n))

(a) 走到 (b)

不走新边,那么距离 (len_1=dis(a,b))

因为树上的边可以随便走,所以只要 (len_1)(k) 同奇偶并且 (len_1 le k) 那么就可以输出 ( exttt{YES})

否则,就强制走新边

有两种情况,一种是从 (a) 走到 (x) ,再过新边走到 (y) ,再从 (y) 走到 (b)

(len_2=dis(a,x)+1+dis(y,b))

一种是从 (a) 走到 (y) ,再过新边走到 (x) ,再从 (x) 走到 (b)

(len_3=dis(a,y)+1+dis(x,b))

对于 (len_2)(len_3) ,跟上面 (len_1) 一样判断就行了

时间复杂度 (O(qlog n))

// This code wrote by chtholly_micromaker(MicroMaker)
#include <bits/stdc++.h>
#define reg register
#define int long long
using namespace std;
const int MaxN=300050;
struct Edge
{
    int nxt,to;
}E[MaxN<<2];
template <class t> inline void read(t &s)
{
    s=0;
    reg int f=1;
    reg char c=getchar();
    while(!isdigit(c))
    {
        if(c=='-')
            f=-1;
        c=getchar();
    }
    while(isdigit(c))
        s=(s<<3)+(s<<1)+(c^48),c=getchar();
    s*=f;
    return;
}
int hd[MaxN],en,n;
int up[MaxN][21],dep[MaxN];
inline void adde(int u,int v)
{
    ++en;
    E[en]=(Edge){hd[u],v};
    hd[u]=en;
    return;
}
inline void dfs(int u,int fa)
{
    up[u][0]=fa;
    for(int i=hd[u];~i;i=E[i].nxt)
    {
        reg int v=E[i].to;
        if(v==fa)
            continue;
        dep[v]=dep[u]+1;
        dfs(v,u);
    }
    return;
}
inline void Init_lca()
{
    for(int k=1;k<21;++k)
        for(int i=1;i<=n;++i)
            up[i][k]=up[up[i][k-1]][k-1];
    return;
}
inline int lca(int u,int v)
{
    if(dep[u]<dep[v])
        swap(u,v);
    if(u!=v)
        for(int k=20;k>=0;--k)
            if(dep[up[u][k]]>=dep[v])
                u=up[u][k];
    if(u==v)
        return u;
    for(int k=20;k>=0;--k)
        if(up[u][k]!=up[v][k])
            u=up[u][k],v=up[v][k];
    return up[u][0];
}
inline int getdis(int u,int v)
{
    return dep[u]+dep[v]-2*dep[lca(u,v)];
}
signed main(void)
{
    memset(hd,-1,sizeof hd);
    reg int u,v;
    cin>>n;
    for(int i=1;i<n;++i)
    {
        read(u);read(v);
        adde(u,v);
        adde(v,u);
    }
    dep[1]=1;dfs(1,0);
    Init_lca();
    int q;cin>>q;
    reg int a,b,k;
    for(int i=1;i<=q;++i)
    {
        read(u);read(v);read(a);read(b);read(k);
        reg int len=getdis(a,b);
        if((len%2==k%2)&&len<=k)
        {
            puts("YES");
            continue;
        }
        reg int len1=getdis(a,u)+getdis(b,v)+1;
        if(len1==k)
        {
            puts("YES");
            continue;
        }
        reg int len2=getdis(a,v)+getdis(b,u)+1;
        if(len2==k)
        {
            puts("YES");
            continue;
        }
        if((len1%2==k%2)&&len1<=k)
        {
            puts("YES");
            continue;
        }
        if((len2%2==k%2)&&len2<=k)
        {
            puts("YES");
            continue;
        }
        // printf("<test> %d %d %d
",len,len1,len2);
        puts("NO");
    }
    return 0;
}

以上是关于CF1304E 1-Trees and Queries的主要内容,如果未能解决你的问题,请参考以下文章

[CF1304E] 1-Trees and Queries - LCA

CF-div2-620-E. 1-Trees and Queries LCA 树上点距离

1-Trees and Queries

E. 1-Trees and Queries

Codeforces 1304E. 1-Trees and Queries

使用 sql union 子查询组合来处理客户过滤的 AND/OR 条件组合