zoukankan      html  css  js  c++  java
  • 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
    ",e);}
    	  	
    	  }
    	}
    	if (sign==0) printf("-1
    ");
    }
    

  • 相关阅读:
    数据加密算法详解
    自定义标签+阻尼动画+圆角图片+titleBar随滑动渐隐和显示
    Android MVP Plugin,一键完成MVP结构代码编写
    jquery-validate校验
    C# 后台获取请求来源、文件下载
    【通用邮件发送】C# QQ 网易邮箱
    【asp.net mvc】 扩展 htmlhelper 实现分页
    在MVC5中使用Ninject 依赖注入
    c# txt 文件上传、写入TXT文件、创建图形验证码
    uploadify图片上传配置
  • 原文地址:https://www.cnblogs.com/nowheretrix/p/9004557.html
Copyright © 2011-2022 走看看