• [Codeforces Round #620 (Div. 2)] E. 1-Trees and Queries(树,LCA,奇偶性)


    [Codeforces Round #620 (Div. 2)] E. 1-Trees and Queries

    time limit per test

    4 seconds

    memory limit per test

    512 megabytes

    input

    standard input

    output

    standard output

    Gildong was hiking a mountain, walking by millions of trees. Inspired by them, he suddenly came up with an interesting idea for trees in data structures: What if we add another edge in a tree?

    Then he found that such tree-like graphs are called 1-trees. Since Gildong was bored of solving too many tree problems, he wanted to see if similar techniques in trees can be used in 1-trees as well. Instead of solving it by himself, he's going to test you by providing queries on 1-trees.

    First, he'll provide you a tree (not 1-tree) with nn vertices, then he will ask you qq queries. Each query contains 55 integers: xx, yy, aa, bb, and kk. This means you're asked to determine if there exists a path from vertex aa to bb that contains exactly kk edges after adding a bidirectional edge between vertices xx and yy. A path can contain the same vertices and same edges multiple times. All queries are independent of each other; i.e. the added edge in a query is removed in the next query.

    Input

    The first line contains an integer nn (3≤n≤1053≤n≤105), the number of vertices of the tree.

    Next n−1n−1 lines contain two integers uu and vv (1≤u,v≤n1≤u,v≤n, u≠vu≠v) each, which means there is an edge between vertex uu and vv. All edges are bidirectional and distinct.

    Next line contains an integer qq (1≤q≤1051≤q≤105), the number of queries Gildong wants to ask.

    Next qq lines contain five integers xx, yy, aa, bb, and kk each (1≤x,y,a,b≤n1≤x,y,a,b≤n, x≠yx≠y, 1≤k≤1091≤k≤109) – the integers explained in the description. It is guaranteed that the edge between xx and yy does not exist in the original tree.

    Output

    For each query, print "YES" if there exists a path that contains exactly kk edges from vertex aa to bb after adding an edge between vertices xx and yy. Otherwise, print "NO".

    You can print each letter in any case (upper or lower).

    Example

    input

    Copy

    5
    1 2
    2 3
    3 4
    4 5
    5
    1 3 1 2 2
    1 4 1 3 2
    1 4 1 3 3
    4 2 3 3 9
    5 2 3 3 9
    

    output

    Copy

    YES
    YES
    NO
    YES
    NO
    

    Note

    The image below describes the tree (circles and solid lines) and the added edges for each query (dotted lines).

    img

    Possible paths for the queries with "YES" answers are:

    • 11-st query: 11 – 33 – 22
    • 22-nd query: 11 – 22 – 33
    • 44-th query: 33 – 44 – 22 – 33 – 44 – 22 – 33 – 44 – 22 – 33

    题意:

    给定一个含有n个节点的树,以及q个询问。

    每一个询问给出5个整数,x,y,a,b,k

    代表如果像树中的x节点和y节点之间加一条边,问是否纯在一条路径从a到b(可以同一个节点走多次)距离为k?

    思路:

    我们假设a到b的最短路径长度为L,显然对于任意一个非负整数z,满足存在一个a到b的路径长为(L+2*z)

    所以我们只需要判断是否存在一个路径距离为L,满足:$L leq k $,且L与K同奇偶性。

    通过分析可以得知,对于每一个询问的a,b只有以下三个有意义的路径(即其他的路径可以通过这三条路径加(2*z)得到):

    1、a到b的简单路径(不使用新增加的边)。

    2、(a->x->y->b)

    2、(a->y->x->b)

    分别判断是否有一条路径符合:$L leq k $,且L与K同奇偶性 即可。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
    #define du2(a,b) scanf("%d %d",&(a),&(b))
    #define du1(a) scanf("%d",&(a));
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
    void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    #define N maxn
    std::vector<int> son[N];
    ll depth[N];
    int fa[N][21], in[N], a, b;
    int n;
    int q;
    void dfs(int rt, int prev)
    {
        depth[rt] = depth[prev] + 1;
        fa[rt][0] = prev;
        for (int i = 1; i < 20; i++)
        {
            fa[rt][i] = fa[fa[rt][i - 1]][i - 1];
        }
        for (int i = 0; i < son[rt].size(); i++)
        {
            if (son[rt][i] == prev)
                continue;
            dfs(son[rt][i], rt);
        }
    }
    int LCA(int x, int y)
    {
        if (depth[x] < depth[y])
            swap(x, y);
        for (int i = 19; i >= 0; i--)
        {
            if (depth[x] - (1 << i) >= depth[y])
            {
                x = fa[x][i];
            }
        }
        if (x == y)
        {
            return x;
        }
        for (int i = 19; i >= 0; i--)
        {
            if (fa[x][i] != fa[y][i])
            {
                x = fa[x][i];
                y = fa[y][i];
            }
        }
        return fa[x][0];
    }
    ll dist(int a, int b)
    {
        int u = LCA(a, b);
        ll L = depth[a] + depth[b] - 2ll * depth[u];
        return L;
    }
    int main()
    {
        //freopen("D:\code\text\input.txt","r",stdin);
        //freopen("D:\code\text\output.txt","w",stdout);
        depth[0] = -1;
        n = readint();
        repd(i, 2, n)
        {
            a = readint();
            b = readint();
            son[a].push_back(b);
            son[b].push_back(a);
        }
        dfs(1, 0);
        q = readint();
        int x, y;
        ll k;
        while (q--)
        {
            x = readint();
            y = readint();
            a = readint();
            b = readint();
            k = readll();
            ll disab = dist(a, b);
            ll disaxyb = dist(a, x) + 1 + dist(y, b);
            ll disayxb = dist(a, y) + 1 + dist(x, b);
            int isok = 0;
            ll ans = inf;
            if (disab % 2 == k % 2)
            {
                ans = min(ans, disab);
            }
            if (disaxyb % 2 == k % 2)
            {
                ans = min(ans, disaxyb);
            }
            if (disayxb % 2 == k % 2)
            {
                ans = min(ans, disayxb);
            }
            if (ans <= k)
            {
                isok = 1;
            }
            if (isok)
            {
                printf("YES
    ");
            } else
            {
                printf("NO
    ");
            }
        }
        return 0;
    }
    
    
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    table常用功能总结
    oracle中number类型的数据使用as string 得到的值为null
    Oracle连接超时
    VS重新生成后仍然执行旧代码
    .NET 环境中使用RabbitMQ
    使用CLR Function代替T-SQL函数,优化检索效率
    SQL Server CLR 使用 C# 自定义存储过程和触发器
    OrderBy排序和IComparer的使用
    System.net.mail 使用ssl发送邮件失败
    C#利用CDO.Message发送邮件
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/12323832.html
Copyright © 2020-2023  润新知