|
Dylans loves treeTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 532 Accepted Submission(s): 99
Problem Description
Dylans is given a tree with
N
nodes.
All nodes have a value A[i] .Nodes on tree is numbered by 1∼N . Then he is given Q questions like that: ① 0 x y :change node x′s value to y ② 1 x y :For all the value in the path from x to y ,do they all appear even times? For each ② question,it guarantees that there is at most one value that appears odd times on the path. 1≤N,Q≤100000 , the value A[i]∈N and A[i]≤100000
Input
In the first line there is a test number
T
.
( T≤3 and there is at most one testcase that N>1000 ) For each testcase: In the first line there are two numbers N and Q . Then in the next N−1 lines there are pairs of (X,Y) that stand for a road from x to y . Then in the next line there are N numbers A1..AN stand for value. In the next Q lines there are three numbers (opt,x,y) .
Output
For each question ② in each testcase,if the value all appear even times output "-1",otherwise output the value that appears odd times.
Sample Input
Sample Output
Source
|
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define BUG puts("BUG is here!");
const int N = 100010;
int level[N], pre[N], son[N], size[N];
int top[N], lct[N];
int ary[N << 2];
int head[N];
int n, lct_in_tree;
struct node{
int v, next;
};
vector<node> E;
void push_up(int rt) {
ary[rt] = ary[rt << 1] ^ ary[rt << 1 | 1];
}
void update(int pos, int x, int l, int r, int rt) {
if (l == r) {
ary[rt] = x;
return ;
}
int m = (l + r) >> 1;
if (pos <= m)
update(pos, x, lson);
else
update(pos, x, rson);
push_up(rt);
}
int query(int a, int b, int l, int r, int rt) {
if (a <= l && r <= b)
return ary[rt];
int m = (l + r) >> 1;
int ans = 0;
if (a <= m)
ans ^= query(a, b, lson);
if (b > m)
ans ^= query(a, b, rson);
return ans;
}
void Init() {
memset(head, -1, sizeof(head));
memset(ary, 0, sizeof(ary));
E.clear();
pre[1] = 1;
level[1] = 1;
son[0] = 0;
lct_in_tree = 0;
}
void add_edge(int u, int v) {
node tmp;
tmp.v = v;
tmp.next = head[u];
head[u] = E.size();
E.push_back(tmp);
}
void dfs(int u) {
size[u] = 1;
son[u] = 0;
for (int i = head[u]; i != -1; i = E[i].next) {
int v = E[i].v;
if (v != pre[u]) {
pre[v] = u;
level[v] = level[u] + 1;
dfs(v);
size[u] += size[v];
if (size[son[u]] < size[v])
son[u] = v;
}
}
}
void build_tree(int u, int tp) {
lct[u] = ++lct_in_tree;
top[u] = tp;
if (son[u])
build_tree(son[u], tp);
for (int i = head[u]; i != -1; i = E[i].next) {
int v = E[i].v;
if (v != pre[u] && v != son[u])
build_tree(v, v);
}
}
int slove(int a, int b) {
int p1 = top[a], p2 = top[b];
int ans = 0;
while (p1 != p2) {
if (level[p1] > level[p2]) {
swap(a, b);
swap(p1, p2);
}
ans = ans ^ query(lct[p2], lct[b], 1, n, 1);
b = pre[p2];
p2 = top[b];
}
if (level[a] > level[b])
swap(a, b);
ans = ans ^ query(lct[a], lct[b], 1, n, 1);
if (ans == -1) ans = 0;
else if (ans == 0) ans = -1;
return ans;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
Init();
int q;
scanf("%d%d", &n, &q);
int a, b;
for (int i = 1; i < n; ++i) {
scanf("%d%d", &a, &b);
add_edge(a, b);
add_edge(b, a);
}
dfs(1);
build_tree(1, 1);
int x;
for (int i = 1; i <= n; ++i) {
scanf("%d", &x);
if (x == 0) x = -1;
update(lct[i], x, 1, n, 1);
}
while (q--) {
scanf("%d%d%d", &x, &a, &b);
if (!x) {
if (b == 0) b = -1;
update(lct[a], b, 1, n, 1);
}
else
printf("%d\n", slove(a, b));
}
}
return 0;
}