zoukankan      html  css  js  c++  java
  • [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/ 希望所写的文章对您有帮助。
  • 相关阅读:
    使用 HttpClient 调用第三方接口
    Servlet 的生命周期及工作原理
    SpringBoot 框架简介及搭建
    使用 SimpleDateFormat 获取上个月的日期
    LoadRunner常见问题(一)
    Web_reg_find()函数的使用
    IEtester调试IE6,IE7,IE8,IE9的CSS兼容性的免费工具
    web_find()函数检查中文字符串失败的处理方法
    lr_shoami()的用法
    IP欺骗经验总结
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/12323832.html
Copyright © 2011-2022 走看看