题目:给出N个数,给出一些条件,x[i]=v或者 x[i]^x[j]=k,然后给出一些询问,x[a1]^x[a2]……
http://acm.hdu.edu.cn/showproblem.php pid=3234
经典的并查集
类似很多题目一样,记录某个结点与根结点的关系,即与根结点的异或值
如果pre[a]=ra,pre[b]=rb;那么合并之后是什么情况呢,即r[a]=num[a]^num[ra];r[b]=num[b]^num[rb];以因为r[a]^r[b]=c
现在要求的是num[ra]=num[ra]^num[rb]=r[a]^r[b]^c;
合并就没有问题了,但是还有个问题是,给出的条件有两个,如果只是单个结点的该怎么办呢
加入一个冗余结点就行了,标号为n,值为0,任何数和0异或还为本身。
剩下的是查询,如果查询的某个数存在于某个集合中。
如果根为我们加入的冗余结点,那么显然r[x]=num[x],直接异或起来就行了。
如果不是冗余结点,r[x]=r[x]^r[pre[x]],则多异或了一次根结点,如果某个集合中的个数为偶数,那么偶数次异或,刚好把根消掉,如果为奇数则说明不可判断。
[cpp]
#include
#include
#include
#include
#include
#include