Christmas Tree

Christmas time is almost here! Families are getting ready for this by buying decorated evergreen trees.The christmas tree contains n nodes numbered from 0 to n n 1 and rooted at node 0. Alice and Bob areplaying around with the new tree and they will play a game using the tree in order to kill their boredom.Alice will carry a coloring marker and Bob will call out two types of instructions:

• +x, this means that Alice will color the node numbered x.

• −x, this means that Alice will clear the color on the node numbered x.

After each of these instructions, Alice should call out the lowest common ancestor (see note for definition)of all the colored nodes so far. Can you help Alice to reply to Bob’s queries as fast as possible ?

Input

Your program will be tested on one or more test cases. The first line of the input will be a single integer T, the number of test cases (1 ≤ T ≤ 100). Followed by T test cases. The first line of each test cases will contain one integer N, the number of nodes in the tree (1 ≤ N ≤ 10^5).The following N - 1 lines willeach contain a pair of integers x and y separated by a single space (0 ≤ x, y ≤ N - 1) which means that node x is connected to node y. It’s guaranteed that the given edges will form a tree. The following line will contain one integer Q, the number of instructions Bob will say (1 ≤ Q ≤ 4 × 1 ^5). The following Q lines will each contain an instruction that Bob called out in the format of qi ai where qi ∈ {+ , -} and(0 ≤ ai ≤ N-1). It’s guaranteed that the clear instruction will only be applied on a colored node and the color instruction on an uncolored node)

Output

For each test instruction that Bob calls out, print a single line containing an integer corresponding toAlice’s response to what is the lowest common ancestor of all the colored nodes or -1 if there are nocolored nodes.Page 1 of

样例输入
1
10
1 4
5 4
1 0
6 8
6 1
1 3
7 6
9 7
9 2
7
+ 2
+ 8
+ 0
- 0
+ 9
- 9
+ 1
样例输出
2
6
0
6
6
6
1

题目长得和异象石很像,解决方法也和那道题相似,不过比那道题简单。

#include<bits/stdc++.h>

using namespace std;
const int N = 1e5 + 10;
int head[N], ver[N << 1], Next[N << 1], tot;
int t, f[N][20], d[N];
int T, n, q;
int dfn[N], mp[N], tc;
set<int> st;

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

inline void init() {
    memset(d, 0, sizeof(d));
    memset(head, 0, sizeof(head));
    st.clear(), tot = tc = 0;
}

inline void read() {
    scanf("%d", &n);
    t = (int) log2(n) + 1;
    for (int i = 1; i <= n - 1; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        add(x, y), add(y, x);
    }
    scanf("%d", &q);
}

void dfs(int x) {
    dfn[x] = ++tc, mp[tc] = x;
    for (int i = head[x]; i; i = Next[i]) {
        int y = ver[i];
        if (d[y])continue;
        d[y] = d[x] + 1;
        f[y][0] = x;
        for (int j = 1; j <= t; j++)
            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);
    for (int i = t; i >= 0; i--)
        if (d[f[y][i]] >= d[x])
            y = f[y][i];
    if (x == y)
        return x;
    for (int i = t; i >= 0; i--)
        if (f[x][i] != f[y][i])
            x = f[x][i], y = f[y][i];
    return f[x][0];
}

void solve() {
    char a;
    for (int i = 1; i <= q; i++) {
        getchar();
        a = getchar();
        int b;
        scanf("%d", &b);
        if (a == '+')st.insert(dfn[b]);
        else st.erase(dfn[b]);
        if (st.empty())puts("-1");
        else printf("%d\n", lca(mp[*st.begin()], mp[*(--st.end())]));
    }
}

int main() {
    scanf("%d", &T);
    while (T--) {
        init();
        read();
        d[0] = 1;
        dfs(0);
        solve();
    }
    return 0;
}
发布了329 篇原创文章 · 获赞 28 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_45323960/article/details/104958170