Luogu2420 让我们异或吧

题目描述

异或是一种神奇的运算,大部分人把它总结成不进位加法.

在生活中…xor运算也很常见。比如,对于一个问题的回答,是为1,否为0.那么:

(A是否是男生 )xor( B是否是男生)=A和B是否能够成为情侣

好了,现在我们来制造和处理一些复杂的情况。比如我们将给出一颗树,它很高兴自己有N个结点。树的每条边上有一个权值。我们要进行M次询问,对于每次询问,我们想知道某两点之间的路径上所有边权的异或值。

输入输出格式

输入格式:

输入文件第一行包含一个整数N,表示这颗开心的树拥有的结点数,以下有N-1行,描述这些边,每行有3个数,u,v,w,表示u和v之间有一条权值为w的边。接下来一行有一个整数M,表示询问数。之后的M行,每行两个数u,v,表示询问这两个点之间的路径上的权值异或值。

输出格式:

输出M行,每行一个整数,表示异或值

输入输出样例

输入样例#1: 复制
5
1 4 9644
2 5 15004
3 1 14635
5 3 9684
3
2 4
5 4
1 1
输出样例#1: 复制
975
14675
0
 1 //2018年2月9日21:03:35
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int N = 200010;
 8 int n, m;
 9 int dep[N];
10 
11 int fir[N], nxt[N], to[N], edge_num, w[N];
12 
13 void addEdge(int x, int y, int z){
14     to[++edge_num] = y;
15     nxt[edge_num] = fir[x];
16     w[edge_num] = z;
17     fir[x] = edge_num;
18 }
19 
20 void dfs(int x, int fa){
21     for(int i=fir[x]; i; i=nxt[i]){
22         int v = to[i];
23         if(v != fa){
24             dep[v] = w[i]^dep[x];
25             dfs(v, x);
26         }
27     }
28 }
29 
30 int main(){
31     scanf("%d", &n);
32     for(int i=1;i<=n-1;i++){
33         int u, v, z;
34         scanf("%d%d%d", &u, &v, &z);
35         addEdge(u, v, z);
36         addEdge(v, u, z);
37     }
38     dfs(1, 0);
39     scanf("%d", &m);
40     for(int i=1;i<=m;i++){
41         int u, v;
42         scanf("%d%d", &u, &v);
43         printf("%d\n", dep[u]^dep[v]);
44     }
45 
46     return 0;
47 }

 

posted @ 2018-02-14 11:46  sinEagle  阅读(157)  评论(0编辑  收藏  举报