题意:对于n个数X[0]~X[n-1],但你不知道它们的值,通过逐步提供给你的信息,你的任务是根据这些信息回答问题,有三种信息如下:

I p  v : Xp = v;    Xp 的值为v

I p q v :  Xp ^ Xq = v;   Xp 异或Xq的值为v

Q k X1 X2 X3 ..... Xk  : 问X1异或X2异或X3....异或Xk的值为多少?

解题思路:先看处理部分(I),有两种 I 一种 是后面有两个整数的,一种是后面有三个整数的,(这里的输入要注意整数有可能是好几个字符)。先看三个整数的,Xp ^ Xq = v;那么我们可以利用并查集把 使 p 的父节点 为 q,再建立一个数组w[],代表Xp 异或 根节点的值,我们对于每次给出的两个数,p 和 q,把它们并到集合里面,利用路径压缩使得w[p]和w[q]都是和根节点异或的值,在压缩的时候维护这个数组就好。

首先我们需要知道几个公式  a ^ b= c, 那么   a = b ^ c  b = a ^ c;

异或运算有结合律,交换律。

a ^ a = 0;

a ^ 0 = a;

对于 I p q v :   p ^ q = v;

假设:

fp  是  p 的根节点,那么 fp = p ^ w[p];     1

fq  是  q 的根节点,那么 fq = q ^ w[q];     2

p ^ q = v ;          3

我们把 fp 的父节点设为 fq(新的根节点) 那么  w[fp] = fp ^ fq;   4

把 1 2 3 式带到 4  式的  w[fp] = w[p] ^ w[q] ^ v;

这样就解决了路径压缩过程中的维护数组问题。对于 I  后面仅有 二个整数的情况,I  p v   p = v;我们可以变形一下   p ^ 0 = v;这样是不是就和上面那种情况很像了呢,即令 q = 0,就好了,因为 我们的编号是  0 ~ N- 1,为了不和其他节点弄混,那么我们可以把这个节点用编号 n 来表示,只不过已知 n 的值为 0 就好了~~~~,然后处理数据这部分就解决了~~~~

紧接着我们看询问部分(Q),询问的时候 假设 询问的是 X1,X2,X3..........Xn,

我们先看 w[X1] ^ w[X2]^w[X3]^....w[Xn],假设他们的根节点是  R(他们在一个集合里面),

那么w[X1] ^ w[X2]^w[X3]^....w[Xn]

=  X1 ^R ^  X2 ^R ^ X3  ^ R ^ ......... ^ Xn ^ R

这里一共有 N 个 R  ,由公式  a ^ a= 0;  a ^ 0 = a;而且异或具有交换律,那么 这里的 N 如果是 偶数 我们 就可以求得X1 ^R ^  X2 ^R ^ X3  ^ R ^ ......... ^ Xn ^ R = X1 ^ X2 ^ X3 ^ ......^Xn,如果是奇数那么最后就会剩下一个单独的R。。。这里这个 R 是已知的话那么也可以求出来 ,怎么会是已知的呢?我们可以想想有一个特殊的  ,就是那个编号为 N 的节点,他的值是 0 ,所以就要分情况了

if(R是N)

{

X1 ^ X2 ^ X3 ^ ......^Xn =w[X1] ^ w[X2] ^ w[X3] ^....w[Xn];

}

else

{

if(R的数量是奇数)

{

不知道值;

}

else

{

X1 ^ X2 ^ X3 ^ ......^Xn =w[X1] ^ w[X2] ^ w[X3] ^....w[Xn];

}

}

这样整个过程就结束了。。。。。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std; const int MAXN = 2e4 + ;
int pre[MAXN]; //存放的是父节点
int weight[MAXN]; //存放是与根节点的异或值
int xp[MAXN]; //询问时的数
int n; int Find(int x) //带路径压缩的查找
{
// printf("1");
if(x != pre[x])
{
int fx = pre[x];
pre[x] = Find(pre[x]);
weight[x] ^= weight[fx]; //维护数组
//printf("2");
}
return pre[x];
} int mix(int x, int y, int z)
{
int fx = Find(x);
int fy = Find(y);
//printf("x = %d y = %d z = %d fx = %d fy = %d\n",x,y,z,fx,fy);
if(fx == fy) //如果给出的两个数已经出现过。判断现在给出的这个 I 是不是和以前的冲突(矛盾)
{
if((weight[x] ^ weight[y]) != z) //(出现了矛盾)
return ;
return ;
}
if(fx == n) fx ^= fy ^= fx ^= fy; //为了使得 n 成为 根节点
pre[fx] = fy;
weight[fx] = weight[x] ^ weight[y] ^ z; //fx 的父节点设为 fy(新的根节点)后维护weight[fx]的值
return ;
} int solv(int key)
{
int index[MAXN]={};
int ans = ;
for(int i = ; i < key ; i++) //查找森林中的每个树,统计 根节点被异或的次数
{
if(index[i]) continue;
int fi = Find(xp[i]);
int cnt = ;
for(int j = i ; j < key; j++)
{
int fj = Find(xp[j]);
if(index[j] == && fi == fj)
{
cnt++;
index[j] = ;
ans ^= weight[xp[j]];
}
}
if((cnt&) && fi != n) //根节点被异或的次数是奇数 而且不是那个特殊的根节点
return -;
}
return ans;
} int main()
{
//freopen("in.cpp","r",stdin);
int Q;
int kas = ;
while(scanf("%d%d",&n,&Q) && (n || Q))
{
printf("Case %d:\n",kas++);
for(int i = ; i <= MAXN; i++) //初始化 开始每个点都是一棵树,自身异或自身是 0 ,
{
pre[i] = i;
weight[i] = ;
}
int facts = ;
int flag = ;
while(Q--)
{
char order[]={};
scanf("%s",order);
int p,q,v;
if(order[] == 'I')
{
facts++;
getchar();
char str[]={};
gets(str);
int k = ;
for(int i = ; str[i] != '\0'; i++)
if(str[i] == ' ') k++;
if(k == )
{
sscanf(str,"%d%d",&p,&v); //I 后面只有两个数
q = n;
}
else
{
sscanf(str,"%d%d%d",&p,&q,&v);//I 后面只有三个数
}
if(flag) continue; //矛盾
if(mix(p,q,v) == ) //矛盾了
{
printf("The first %d facts are conflicting.\n",facts);
flag = ;
}
}
else if(order[] == 'Q')
{
int k;
scanf("%d",&k);
memset(xp,,sizeof(xp));
for(int i = ; i < k; i++)
{
scanf("%d",&xp[i]);
}
if(flag) continue;//矛盾
int ans = solv(k);
if(ans == -)
{
printf("I don't know.\n");
}
else
printf("%d\n",ans);
}
}
printf("\n");
}
return ;
}

UVALive(LA) 4487 Exclusive-OR(带权并查集)的更多相关文章

  1. UVALive 3027 Corporative Network (带权并查集)

    题意: 有 n 个节点,初始时每个节点的父节点都不存在,你的任务是执行一次 I 操作 和 E 操作,含义如下: I  u  v   :  把节点 u  的父节点设为 v  ,距离为| u - v | ...

  2. UVALive 3027 Corporative Network 带权并查集

                         Corporative Network A very big corporation is developing its corporative networ ...

  3. POJ1733 Party game [带权并查集or扩展域并查集]

    题目传送 Parity game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10870   Accepted: 4182 ...

  4. POJ 1703 Find them, Catch them(带权并查集)

    传送门 Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42463   Accep ...

  5. [NOIP摸你赛]Hzwer的陨石(带权并查集)

    题目描述: 经过不懈的努力,Hzwer召唤了很多陨石.已知Hzwer的地图上共有n个区域,且一开始的时候第i个陨石掉在了第i个区域.有电力喷射背包的ndsf很自豪,他认为搬陨石很容易,所以他将一些区域 ...

  6. poj1417 带权并查集 + 背包 + 记录路径

    True Liars Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2713   Accepted: 868 Descrip ...

  7. poj1984 带权并查集(向量处理)

    Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 5939   Accepted: 2 ...

  8. 【BZOJ-4690】Never Wait For Weights 带权并查集

    4690: Never Wait for Weights Time Limit: 15 Sec  Memory Limit: 256 MBSubmit: 88  Solved: 41[Submit][ ...

  9. hdu3038(带权并查集)

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=3038 题意: n表示有一个长度为n的数组, 接下来有m行形如x, y, d的输入, 表示 ...

随机推荐

  1. leetcode 【 Remove Duplicates from Sorted List 】 python 实现

    题目: Given a sorted linked list, delete all duplicates such that each element appear only once. For e ...

  2. Python程序执行时的不同电脑路径不同问题

    原因:因代码转移时项目路径发生了变化,导致解释器无法找到对应路径,是的程序无法正常执行 需求: 1.我希望代码能在不同的电脑下,不必修改源代码就能正常执行(所需模块已安装的前提下) 2.我希望代码在命 ...

  3. python 学习分享-select等

    首先列一下,sellect.poll.epoll三者的区别 select select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组(在linux中 ...

  4. 牛客网暑期ACM多校训练营(第一场):J-Different Integers(分开区间不同数+树状数组)

    链接:J-Different Integers 题意:给出序列a1, a2, ..., an和区间(l1, r1), (l2, r2), ..., (lq, rq),对每个区间求集合{a1, a2, ...

  5. bash语法注意点

    bash 语法注意点 =和不能分开 如: val=expr $a + $b` [空格 *** 空格]条件判断要有空格 如: if [ $a ==$b ] 表达式和运算符之间要有空格, $a空格 + 空 ...

  6. Struts2+DAO层实现实例01——搭建Struts2基本框架

    实例内容 利用Strust2实现一个登陆+注册功能的登陆系统. 实现基础流程:

  7. BETA0

    目录 过去存在的问题 任务分工 规范 后端总结 卉卉 家灿 前端总结 绪佩 青元 恺琳 宇恒 丹丹 算法&API接口 家伟 鸿杰 一好 文档&博客撰写 政演 产品功能 我们已经坐了哪些 ...

  8. Application_Start事件中用Timer做一个循环任务

    protected void Application_Start(object sender, EventArgs e) { System.Timers.Timer timer = new Syste ...

  9. axis2实践(一)JAX-WS入门示例

    1. 实例说明 现在大多数的网站都有通知功能(例如,放假通知,网站维护通知等),本实例就是针对于通知,发布两个WebService服务 1)根据供应商编号,状态,发布日期查询通知信息 2)根据编号查询 ...

  10. 湘潭邀请赛 2018 E From Tree to Graph

    题意: 给出一棵树以及m,a,b,x0,y0.之后加m条边{(x1,LCA(x1,y1)),(x2,LCA(x2,y2))...(xm,LCA(xm,ym))}.定义z = f(0)^f(1)^... ...