题目描述

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

在生活中…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。

算法:

LCA+数学

 

分析:

这道题乍眼一看感觉是带权值的最近公共祖先问题,但粗略计算后发现会超时,进一步分析,得到一些有关异或的规律,然后这就是一道暴力的题目。

 

引用一些大佬的资料:

根据题目中对“异或”的定义,我们可以得出异或的真值表,这里我们用a,b代表异或的两个元素,a^b代表a按位异或的值。

    a    b    a^b
    0    0    0
    0    1    1
    1    0    1
    1    1    0

我们发现,如果a==b,那么a^b就是0,否则式子的值就是1。

通过真值表,我们可以发现并证明异或的几个性质。

1.a^b==b^a

异或具有交换律

    a    b    a^b    b^a
    0    0    0        0
    0    1    1        1
    1    0    1        1
    1    1    0        0

2.a^b^c==a^(b^c)

异或具有结合律

    a    b    c    a^b^c    a^(b^c)
    0    0    0    0        0
    0    0    1    1        1
    0    1    0    1        1
    0    1    1    0        0
    1    0    0    1        1
    1    0    1    0        0
    1    1    0    0        0
    1    1    1    1        1

3.a^a==0

异或自己是0

    a    a^a
    0    0
    1    0

4.a^0=a

异或0还是0

    a    a^0
    0    0
    1    1

由以上四点性质,我们可以推出:

a^b^b = a^(b^b)

     =    a^0
    =    a

所以推出如下定理:

异或的逆运算是它本身!!!

讲一下对于本题的具体思路:对于这棵树,随意指定一个根节点,以此点来建树,维护每个点到根节点的距离,两个点u到v的树上路径一定为

u->lca(u,v)->v

第一个过程一定是一直向父亲节点前进,第二个过程一定是一直向儿子节点前进。

(lca(u,v)的定义为u,v的树上最近公共祖先)

那么最后查询的答案一定为

length[u]^length[v] anc^ length[lca(u,v)] anc^ length[lca(u,v)]

其中anc^为^的逆运算,由于之前已经推出anc^等价于^,而两次亦或的结果等价于原结果,所以最后的答案为:

length[u]^length[v]

此处不用考虑特判u或v是根节点的情况。

建树的时间复杂度为O(N),查询只需要O(1)的时间,最后程序的时间复杂度为O(N+M),空间复杂度为O(N)。

 

 

上代码:

 

 #include<cstdio>
#define maxn 100010
using namespace std; int n,m,tot,head[maxn],dis[maxn];
struct node
{
int nxt,to,val;
}edge[maxn<<];
bool vis[maxn]; int read()
{
int x=,f=;
char c=getchar();
while (c<||c>)
f=c=='-'?-:,c=getchar();
while (c>=&&c<=)
x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
} void add(int c,int b,int a)
{
edge[++tot]=(node){head[a],b,c};
head[a]=tot;
edge[++tot]=(node){head[b],a,c};
head[b]=tot;
} int dfs(int u,int Xor)
{
dis[u]=Xor;
vis[u]=;
for (int i=head[u];i;i=edge[i].nxt)
if (!vis[edge[i].to])
dfs(edge[i].to,Xor^edge[i].val);
} int main()
{
int i,j,k,u,v;
n=read();
for (i=;i<=n-;i++)
add(read(),read(),read());
m=read();
dfs(,);
while (m--)
printf("%d\n",dis[read()]^dis[read()]);
return ;
}

【洛谷P2420】让我们异或吧的更多相关文章

  1. 洛谷 P2420 让我们异或吧 解题报告

    P2420 让我们异或吧 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中-xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B ...

  2. 洛谷——P2420 让我们异或吧

    P2420 让我们异或吧 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B ...

  3. 洛谷 [P2420] 让我们异或吧

    某两点之间的路径上所有边权的异或值即dis1^dis2--^disn. 由于x^y^y=x,所以dfs预处理出每一点到根节点的异或值,对于每次询问,直接输出 disu^disv. #include & ...

  4. 洛谷P2420 让我们异或吧(树链剖分)

    题目描述异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是否是男生)=A和B是否能够 ...

  5. [洛谷P2420] 让我们异或吧

    题目链接:让我们异或吧 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是 ...

  6. ⌈洛谷4735⌋⌈BZOJ3261⌋最大异或和【可持久化01Trie】

    题目链接 [BZOJ传送门] [洛谷传送门] 题解 终于学会了可持久化trie树了.感觉并不是特别的难. 因为可持久化,那么我们就考虑动态开点的trie树. 都知道异或操作是有传递性的,那么我们就维护 ...

  7. AC日记——让我们异或吧 洛谷 P2420

    题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B是否是男生)=A和B是否能 ...

  8. skkyk:题解 洛谷P2420 【让我们异或吧】lca+xor前缀和

    刚学了LCA,写篇题解巩固一下 首先题目有误: (A是否是男生 )xor( B是否是男生)=A和B是否能够成为情侣,这句话显然是错误的qwq 对于这道题,容易看出,对于待处理的两个点,只要我们找到他的 ...

  9. 洛谷P4551 最长异或路径

    传送门:https://www.luogu.org/problem/show?pid=4551 在看这道题之前,我们应懂这道题怎么做:给定n个数和一个数m,求m和哪一个数的异或值最大. 一种很不错的做 ...

随机推荐

  1. 机器学习初入门04 – Seaborn(持续更新)

    Seaborn库可以说是在matplotlib库上的一个封装,它给我们提供了非常丰富的模板 一.整体布局风格设置 import seaborn as sns import numpy as np im ...

  2. thinkphp在wamp 配置去掉url中index.php方法

    http://blog.csdn.net/youmypig/article/details/45008971

  3. 《LINUX内核设计与实现》第一、二章学习总结

    第一章 Linux内核简介 (一)Unix是一个强大.健壮和稳定的操作系统,特点是: Unix很简洁,仅仅提供几个几百个系统调用并且有一个非常明确的设计目的 在Unix中,所有的东西都被当作文件对待, ...

  4. Linux内核分析 实验一 ——by王玥

    一.实验内容 1)实验部分(以下命令为实验楼64位Linux虚拟机环境下适用,32位Linux环境可能会稍有不同) 使用 gcc –S –o main.s main.c -m32 命令编译成汇编代码, ...

  5. DirectoryEntry_Properties属性的遍历(win2003)

    DirectoryEntry root = new DirectoryEntry(@"IIS://localhost/W3SVC"); string PInfo = "& ...

  6. ElasticSearch 2 (21) - 语言处理系列之单词识别

    ElasticSearch 2 (21) - 语言处理系列之单词识别 摘要 一个英语单词相对容易识别:因为英语单词是被空格或(某些)标点符号隔开的.但在英语中也有反例:you're 这个词是一个单词还 ...

  7. Week1个人作业

    关于教材的疑问 阅读的教材<构建之法> 1第一章中提到:“软件企业=软件+商业模式”,这样的结构是否过于简单,尤其是在互联网+时代 2.在进行单元测试的时候,怎么做到100%覆盖 3.个人 ...

  8. Alpha冲刺第9天

    Alpha第9天 1.团队成员 郑西坤 031602542 (队长) 陈俊杰 031602504 陈顺兴 031602505 张胜男 031602540 廖钰萍 031602323 雷光游 03160 ...

  9. Linux命令(十二) 分割文件 split 合并文件 join

    一.分割文件 split 命令介绍 当处理文件时,有时需要将文件做分割处理,split 命令用于分割文件,可以分割文本文件,按指定的行数分割,每个分割后的文件都包含相同的行数.split 可以分割非文 ...

  10. Jquery ajax 完整实例子1

    $ajax请求--------------------------------- var $personWifePs=$("#wife-money tbody tr"); var ...