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\) 那么就可以输出 \(\texttt{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(q\log n)\)

// This code wrote by chtholly_micromaker(MicroMaker)
#include 
#define reg register
#define int long long
using namespace std;
const int MaxN=300050;
struct Edge
{
    int nxt,to;
}E[MaxN<<2];
template  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]=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>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(" %d %d %d\n",len,len1,len2);
        puts("NO");
    }
    return 0;
}

你可能感兴趣的:(CF1304E 1-Trees and Queries)