UVA 12232 Exclusive-OR(并查集+思想)
题意:给你n个数,接着三种操作:
I p v :告诉你 Xp = v
I p q v :告诉你 Xp ^ Xq = v
Q k p1 p2 … pk:问你k个数连续异或的结果
注意前两类操作可能会出现与之前告诉你的相矛盾,此时输出“The first n(第几个I) facts are conflicting.”接着一直保持沉默,否则不输出。最后一类询问可能得不到值,就输出“I don’t know.”,否则输出结果
题解:告诉你时使用并查集的合并操作,可以记录权值为此点异或父亲节点的值,祖先节点的权值一定为0(其他值异或0不变),因为:X^X1^X1^X2=X^X2 则可以进行路径压缩。
但是我们知道一个集合的关系时,却不一定知道每个元素各自的大小,所以再记录一个权值2,当一个集合祖先的权值2非负时,表示祖先确定大小了,而这个集合就一定可以知道每个元素的大小,否则就不知道。我们合并时就要注意某子树是否知道每个元素的大小。
询问是首先将明确其大小的值计算出来。而只知道关系一些数:如果有偶数个在同一集合,那这偶数个就可以运用它们间的关系一同求出。
这儿还有一个小麻烦就是当输入I时,后面个数不定,所以可以使用sscanf处理。
真不愧是神题啊,我copy文档的“I don’t know.”居然是错的。。。。。。。。。。。。。。。。。。。。。。。。。。。。错的。。。。。。。。。。。。。。。。。。。。。。。。。。
- #include<set>
- #include<map>
- #include<queue>
- #include<stack>
- #include<cmath>
- #include<vector>
- #include<string>
- #include<cstdio>
- #include<cstring>
- #include<stdlib.h>
- #include<iostream>
- #include<algorithm>
- using namespace std;
- #define eps 1E-8
- /*注意可能会有输出-0.000*/
- #define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
- #define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
- #define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
- #define mul(a,b) (a<<b)
- #define dir(a,b) (a>>b)
- typedef long long ll;
- typedef unsigned long long ull;
- const int Inf=<<;
- const double Pi=acos(-1.0);
- const int Mod=1e9+;
- const int Max=;
- int fat[Max],ran[Max],num[Max];
- int tem[],tem1;
- void Init(int n)
- {
- for(int i=; i<=n; ++i)
- {
- fat[i]=i;
- ran[i]=;
- num[i]=-;
- }
- return;
- }
- int Find(int x)
- {
- if(x==fat[x])
- return fat[x];
- int y=Find(fat[x]);
- ran[x]=(ran[x]^ran[fat[x]]);//异或优先级很低
- return fat[x]=y;
- }
- int Union(int x,int y,int z)
- {
- int x1=Find(x);
- if(y==-)//确定一个值
- {
- if(num[x1]==-)
- {
- num[x1]=(ran[x]^z);
- return ;
- }
- if(num[x1]==(ran[x]^z))
- return ;
- return ;
- }
- int y1=Find(y);
- if(x1==y1)
- {
- if((ran[x]^ran[y])==z)
- return ;
- return ;
- }
- if(num[x1]==-)//x集合不知道每个值得权值
- {
- fat[x1]=y1;
- ran[x1]=(ran[x]^ran[y]^z);
- return ;
- }
- else
- {
- fat[y1]=x1;
- ran[y1]=(ran[x]^ran[y]^z);
- if(num[y1]==-)
- return ;
- else
- {
- if((num[x1]^num[y1])==ran[y1])
- return ;
- return ;
- }
- }
- }
- int Solve(int n)//询问
- {
- int ans=,vis[];
- for(int i=; i<tem1; ++i)
- {
- int x1=Find(tem[i]);
- if(num[x1]!=-)
- {
- ans=(ans^ran[tem[i]]^num[x1]);
- vis[i]=-;
- }
- else//不知道这个值
- {
- ans=(ans^ran[tem[i]]);
- vis[i]=x1;
- }
- }
- sort(vis,vis+tem1);
- int flag=;
- for(int i=; i<tem1; ++i)
- {
- if(vis[i]!=-)//不知道的值要在同集合出现偶数次
- {
- if(flag)
- {
- if(vis[i]!=vis[i-])
- return -;
- flag=;
- }
- else
- flag=;
- }
- }
- if(flag)
- return -;
- return ans;
- }
- int main()
- {
- int n,m;
- int xx1,yy1,val,flag,coun=,tem3;
- char str[];
- while(~scanf("%d %d",&n,&m))
- {
- if(!n&&!m)
- break;
- tem3=;
- printf("Case %d:\n",++coun);
- flag=;
- Init(n);
- for(int i=; i<m; ++i)
- {
- scanf("%s",str);
- if(str[]=='I')
- {
- tem3++;
- getchar();
- gets(str);
- if(flag)
- {
- if(sscanf(str,"%d%d%d",&xx1,&yy1,&val)==)//转化
- {
- val=yy1;
- yy1=-;
- }
- int tem2=Union(xx1,yy1,val);
- if(!tem2)
- {
- printf("The first %d facts are conflicting.\n",tem3);
- flag=;
- }
- }
- }
- else
- {
- scanf("%d",&tem1);
- for(int j=; j<tem1; j++)
- scanf("%d",&tem[j]);
- if(flag)
- {
- int tem2=Solve(n);
- if(tem2==-)
- printf("I don't know.\n");
- else
- printf("%d\n",tem2);
- }
- }
- }
- printf("\n");
- }
- return ;
- }
UVA 12232 Exclusive-OR(并查集+思想)的更多相关文章
- UVA 11987 - Almost Union-Find(并查集)
UVA 11987 - Almost Union-Find 题目链接 题意:给定一些集合,操作1是合并集合,操作2是把集合中一个元素移动到还有一个集合,操作3输出集合的个数和总和 思路:并查集,关键在 ...
- PAT甲级1004题解——并查集思想改
题目分析:本题开始一直在考虑如何将每一个节点通过一种合适的数据结构存储起来(一对多的关系),最后发现借助并查集的思想可以用一个数组p,p[i]存放i节点的父节点,每次查询编号为i的节点属于第几层且判断 ...
- CodeForces 828C String Reconstruction(并查集思想)
题意:给你n个串,给你每个串在总串中开始的每个位置,问你最小字典序总串. 思路:显然这道题有很多重复填涂的地方,那么这里的时间花费就会特别高. 我们维护一个并查集fa,用fa[i]记录从第i位置开始第 ...
- UVA - 1197 (简单并查集计数)
Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized ...
- UVA 10158 War(并查集)
//思路详见课本 P 214 页 思路:直接用并查集,set [ k ] 存 k 的朋友所在集合的代表元素,set [ k + n ] 存 k 的敌人 所在集合的代表元素. #include< ...
- UVA - 11987 Almost Union-Find 并查集的删除
Almost Union-Find I hope you know the beautiful Union-Find structure. In this problem, you're to imp ...
- uva 6910 - Cutting Tree 并查集的删边操作,逆序
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
- UVA - 208 Firetruck(并查集+dfs)
题目: 给出一个结点d和一个无向图中所有的边,按字典序输出这个无向图中所有从1到d的路径. 思路: 1.看到紫书上的提示,如果不预先判断结点1是否能直接到达结点d,上来就直接dfs搜索的话会超时,于是 ...
- UVA 11987 Almost Union-Find 并查集单点修改
Almost Union-Find I hope you know the beautiful Union-Find structur ...
随机推荐
- ffmpeg-20160701-git-bin.7z
ESC 退出 0 进度条开关 1 屏幕原始大小 2 屏幕1/2大小 3 屏幕1/3大小 4 屏幕1/4大小 S 下一帧 [ -2秒 ] +2秒 ; -1秒 ' +1秒 下一个帧 -> -5秒 f ...
- PL/Proxy介绍
PL/Proxy 介绍 一.概述 1.PL/Proxy 是一个采用PL Language语言的数据库分区系统. 目的:轻松访问分区数据库 它的理念是代理远程函数体内指定.函数调用同样标签创建的函数,所 ...
- [Android]如何获取当前用户设置的时区
方法:TimeZone.getDefault().getDisplayName(true, TimeZone.SHORT);获取的值如GMT+08:00,GMT-04:00,EDT 另附:国家码查询 ...
- java获得本机IP,名称等
import java.net.InetAddress; import java.net.UnknownHostException; public class GetLocalIP { public ...
- python基础——map/reduce
python基础——map/reduce Python内建了map()和reduce()函数. 如果你读过Google的那篇大名鼎鼎的论文“MapReduce: Simplified Data Pro ...
- CLR via C#(02)-基元类型、引用类型、值类型
http://www.cnblogs.com/qq0827/p/3281150.html 一. 基元类型 编译器能够直接支持的数据类型叫做基元类型.例如int, string等.基元类型和.NET框架 ...
- Overview and Evaluation of Bluetooth Low Energy: An Emerging Low-Power Wireless Technology
转自:http://www.mdpi.com/1424-8220/12/9/11734/htm Sensors 2012, 12(9), 11734-11753; doi:10.3390/s12091 ...
- java-解决业务操可能数据冲突问题
问题提出,由于业务会出现多人同时操作,或者业务人员反复的操作,因此在业务流程中,需要对业务操作数据进行保护,由于使用数据库锁可能会引起一些难以预料的问题,因此考虑使用内存锁,设计思想:在内存中使用一个 ...
- HDU3364 Lanterns(求矩阵的秩)
求矩阵的秩,及判断有无解 #include<cstdio> #include<iostream> #include<cstdlib> #include<cst ...
- android 入门-android Studio 解决方案
一.当提示 解决方案: 1. 2. 二.从这步到这步 的时候,可能遇见下面的问题. 解决方案: 更新一下build-tools 19.1.0版本 放到你的sdk里并重启as. 三. 当遇见这样的情况 ...