您的位置:首页 > 其它

HDOJ 5274 Dylans loves tree

2015-06-21 15:36 381 查看
欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院 

Dylans loves tree

Time 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

1
3 2
1 2
2 3
1 1 1
1 1 2
1 1 3

 

Sample Output

-1
1

Hint
If you want to hack someone,N and Q in your testdata must smaller than 10000,and you shouldn't print any space in each end of the line.

 

Source

BestCoder Round #45
#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
, pre
, son
, size
;
int top
, lct
;
int ary[N << 2];
int head
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: