欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

1-Trees and Queries

程序员文章站 2024-03-22 17:38:04
...

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 n vertices, then he will ask you q queries. Each query contains 5 integers: x, y, a, b, and k. This means you’re asked to determine if there exists a path from vertex a to b that contains exactly k edges after adding a bidirectional edge between vertices x and y. 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 n (3≤n≤105), the number of vertices of the tree.

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

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

Next q lines contain five integers x, y, a, b, and k each (1≤x,y,a,b≤n, x≠y, 1≤k≤109) – the integers explained in the description. It is guaranteed that the edge between x and y does not exist in the original tree.

Output
For each query, print “YES” if there exists a path that contains exactly k edges from vertex a to b after adding an edge between vertices x and y. Otherwise, print “NO”.

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

Example

input
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
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).

1-Trees and Queries
Possible paths for the queries with “YES” answers are:

1-st query: 1 – 3 – 2
2-nd query: 1 – 2 – 3
4-th query: 3 – 4 – 2 – 3 – 4 – 2 – 3 – 4 – 2 – 3

#include<bits/stdc++.h>

#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define sc(a) scahf("%c",&a);
#define ss(a) scanf("%s",a)
#define pi(a) printf("%d\n",a)
#define pl(a) printf("%lld\n",a)
#define pc(a) putchar(a)
#define ms(a) memset(a,0,sizeof(a))
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define repd(i, a, b) for(register int i=a;i>=b;--i)
#define reps(s) for(register int i=head[s];i;i=Next[i])
#define ll long long
#define ull unsigned long long
#define vi vector<int>
#define vc vector<char>
#define pii pair<int,int>
#define pll pair<long,long>
#define pil pair<int,long>
#define pli pair<long,int>
#define mii unordered_map<int,int>
#define msi unordered_map<string,int>
#define lowbit(x) ((x)&(-(x)))
#define ce(i, r) i==r?'\n':' '
#define pb push_back
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define pr(x) cout<<#x<<": "<<x<<endl
using namespace std;

inline int qr() {
    int f = 0, fu = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-')fu = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        f = (f << 3) + (f << 1) + c - 48;
        c = getchar();
    }
    return f * fu;
}

const int N = 1e5 + 10;
int head[N], ver[N << 1], Next[N << 1], tot;
int n, q, d[N], f[N][20], t;

inline void add(int x, int y) {
    ver[++tot] = y;
    Next[tot] = head[x];
    head[x] = tot;
}

inline void read() {
    n = qr();
    repi(i, 1, n - 1) {
        int x = qr(), y = qr();
        add(x, y), add(y, x);
    }
    q = qr();
}

void dfs(int x) {
    reps(x) {
        int y = ver[i];
        if (d[y])continue;
        d[y] = d[x] + 1;
        f[y][0] = x;
        repi(j, 1, t)f[y][j] = f[f[y][j - 1]][j - 1];
        dfs(y);
    }
}

inline int lca(int x, int y) {
    if (d[x] > d[y])swap(x, y);
    repd(i, t, 0)if (d[f[y][i]] >= d[x])y = f[y][i];
    if (x == y)return x;
    repd(i, t, 0)if (f[x][i] != f[y][i])
            x = f[x][i], y = f[y][i];
    return f[x][0];
}

inline int dis(int x, int y) {
    return d[x] + d[y] - 2 * d[lca(x, y)];
}

inline void solve() {
    while (q--) {
        int x = qr(), y = qr(), a = qr(), b = qr(), k = qr();
        int d1 = dis(a, b);
        if ((d1 & 1) == (k & 1) && d1 <= k)puts("YES");
        else {
            int d2 = min(dis(a, x) + dis(y, b) + 1, dis(a, y) + dis(x, b) + 1);
            if ((d2 & 1) == (k & 1) && d2 <= k)puts("YES");
            else puts("NO");
        }
    }
}

int main() {
    read();
    t = (int) log2(n) + 1;
    d[1] = 1;
    dfs(1);
    solve();
    return 0;
}
相关标签: ACM