洛谷 2420 让我们异或吧

来源:互联网 发布:禅道部署到linux 编辑:程序博客网 时间:2024/05/18 16:16

题目描述

异或是一种神奇的运算,大部分人把它总结成不进位加法.在生活中…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

说明

对于40%的数据,有1 ≤ N,M ≤ 3000;

对于100%的数据,有1 ≤ N ,M≤ 100000。

/**************************    Name:let us ^    How to get:luogu.org    By:Shine_Sky**************************//*******************************    这道题可以说完全可以当做前向星练习题    我们将dis[]数组当作结点1到其他边的异或值    因为a^b^c^d=(a^b)^(c^d)    而且a^b=a^b^c^c所以结点u和结点v的边异或值    就为dis[v]^dis[u]所以就这样过了 *******************************/#include<iostream>#include<cstdio>#define f(i,a,b) for(register int i=a;i<=b;i++)#define fd(i,a,b) for(register int i=a;i>=b;i--)using namespace std;inline int read(){    int data=0,w=1; char ch=0;    while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();    if(ch=='-') w=-1,ch=getchar();    while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();    return data*w;}inline void write(int x){    if(x<0) putchar('-'),x=-x;    if(x>9) write(x/10);    putchar(x%10+'0');}const int N=100000+7;struct Node{    int next,node,w;    }h[N*2];int head[N*2],n,m,tot,dis[N];bool book[N];inline void Add_Node(int u,int v,int w){    h[++tot].next=head[u];    head[u]=tot;    h[tot].node=v;    h[tot].w=w;}inline void travel(int now,int sum)//所遍历到的结点,累计异或值 {    dis[now]=sum;    for(register int i=head[now];i;i=h[i].next)    {        int node=h[i].node,w=h[i].w;        if(!book[node])        {            book[node]=1;            travel(node,w^sum);        }    }}int main(){    n=read();    f(i,2,n)    {        int u=read(),v=read(),w=read();        Add_Node(u,v,w);        Add_Node(v,u,w);        }    m=read();    travel(1,0);//从结点出发(强行认为1是更结点)     f(i,1,m)    {        int u,v;        u=read();v=read();        int ans=dis[u]^dis[v];        write(ans);        puts("");    }    return 0;}
原创粉丝点击