nowcoder—Beauty of Trees
Posted 跟我一起这样做
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nowcoder—Beauty of Trees相关的知识,希望对你有一定的参考价值。
Beauty of Trees
现在有一条数组,给定长度,可是却不知道数组中的元素。有m个命题,每次给你l,r,和k。表达的意思是,从l到r的异或和为k。如果你能根据已知真命题,确定这是一个假命题,那么输出命题的编号。如果是真命题,不需要操作。如果你不知道这是真命题还是假命题,那么把这个命题当作真命题。
权值并查集即可。
对于每个命题,首先判断两个结点是否在同一颗树上。若在同一颗树上,代表这两点之间的异或值存在而且已知。那么查询一下。记录(l-1)到根的val值为x,记录r到根的val值为y,x^y即为这两个点的异或值。与k比较。
若两个点不在一棵树上,代表这两个点间的异或值未知,那么按照要求,把这个命题当作是真命题。所以需要将这两颗树合并。记录x为l-1到他的根的异或值,记录y为r到他的根的异或值。此时,我们可以发现,x^y^k即为两个根之间的异或值。由于两根的初始val为空,所以只需要将其中一个点的val修改为x^y^k即可。
#include"stdio.h" #include"string.h" int val[105000]; int father[105000]; int getfather(int k){ if (k==father[k]) return k; int tmp=father[k]; father[k]=getfather(father[k]); val[k]=val[k]^val[tmp]; return father[k]; } int main(){ int n,m,i,e,t,xx,yy,a,b,x,y,k,tmp; int sign=0; scanf("%d %d",&n,&m); memset(val,0,sizeof(val)); for (i=0;i<=n;i++) father[i]=i; for (e=1;e<=m;e++){ scanf("%d %d %d",&x,&y,&k); x--; if (x>y) { tmp=x;x=y;y=tmp; } xx=getfather(x); yy=getfather(y); a=val[x]; b=val[y]; if (xx!=yy){ father[yy]=xx; val[yy]=k^a^b; }else { if ((a^b)==k) ; else {sign=1;printf("%d\n",e);} } } if (sign==0) printf("-1\n"); }
以上是关于nowcoder—Beauty of Trees的主要内容,如果未能解决你的问题,请参考以下文章