CF1304E 1-Trees and Queries

题目链接

对树的路径进行操作,不难想到树的路径是唯一的,离不开LCA

添加一条新边后,答案有两种可能,一是走原树上路径,二是通过这条边走到

对于后者,其实答案就是dis(a,x)+1+dis(y,b)或者dis(a,y)+1+dis(x,b)

均是树上原有的,LCA可求

但是有个特殊情况,可以反复横跳(恶心心

但是反复横跳的奇偶性不变,只要有一个答案<=K并且和K奇偶性相同即可

#include <cstdio>
#include <iostream>
using namespace std;

#define MAXN 100005

struct edge {
    int v,next;
} G[MAXN<<1];
int head[MAXN],tot = 0;

inline void add(int u,int v) {
    G[++tot].v = v; G[tot].next = head[u]; head[u] = tot;
}

struct Tree {
    int son[MAXN],size[MAXN],fa[MAXN],d[MAXN];
    int top[MAXN];

    void dfs1(int u,int father) {
        fa[u] = father; d[u] = d[father] + 1;
        size[u] = 1; son[u] = 0;
        for(int i=head[u];i;i=G[i].next) {
            int v = G[i].v; if(v==fa[u]) continue;
            dfs1(v,u); size[u] += size[v];
            if(size[v]>size[son[u]]) son[u] = v; 
        }
    }

    void dfs2(int u,int tp) {
        top[u] = tp;
        if(son[u]) dfs2(son[u],tp);
        for(int i=head[u];i;i=G[i].next) {
            int v = G[i].v; if(v==fa[u]||v==son[u]) continue;
            dfs2(v,v);
        }
    }

    inline void init() {
        d[1] = size[0] = 0;
        dfs1(1,1); dfs2(1,1);
    }

    inline int LCA(int u,int v) {
        while(top[u]!=top[v]) {
            if(d[top[u]]<d[top[v]]) swap(u,v);
            u = fa[top[u]];
        }
        return d[u]>d[v]?v:u;
    }
    inline int dis(int u,int v) {
        int lca = LCA(u,v);
        return (d[u]-d[lca]) + (d[v]-d[lca]);
    }
} tr;

inline bool check(int dis1,int dis2) {
    return (dis1<=dis2&&(dis1&1)==(dis2&1));
}

int N,Q;

int main() {

    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    cin >> N;
    for(int i=1;i<N;++i) {
        int u,v; cin >> u >> v;
        add(u,v); add(v,u);
    }

    tr.init();

    cin >> Q;
    for(int i=1;i<=Q;++i) {
        int x,y,a,b,k; cin >> x >> y >> a >> b >> k;
        if(check(tr.dis(a,b),k)||check(tr.dis(a,x)+1+tr.dis(y,b),k)||check(tr.dis(a,y)+1+tr.dis(x,b),k)) cout << "YES\n";
        else cout << "NO\n";
    }

    return 0;
}
上一篇:dependency check工具的使用


下一篇:给你一个字符串数组 words ,只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。 美式键盘 中: 第一行由字符 “qwertyuiop“ 组成。 第二行由字符 “asdf