已知有 x[0-(n-1)],但是不知道具体的值,题目给定的信息 只有 I P V,说明 Xp=V,或者 I P Q V,说明 Xp ^ Xq=v,然后要求回答每个询问,询问的是 某任意的序列值 Xp1^Xp2,,,,X^pk

这个题目用加权并查集是这么处理的:

1. f[]照样是代表父节点,照样进行路径压缩,把每个 V[i]=V[i]^V[f[i]],即节点存储的值实际是它与它父亲的异或的值。为什么要这样呢,因为异或首先满足交换律,而且异或同一个数偶数次,即相当于本身,那么这个题目的其中一个要求是探测冲突,则如果两个点同属一个集合,那么 他们的 Xp^Xq=Xp^Xf^Xq^Xf=v[p]^v[q],就是利用了异或偶数次等于本身的原理,在真正计算的时候,也是这样,只有父节点被异或了偶数次 才可以被消除,求得真正的值,只有其中有一个或者以上的父节点经过了奇数次的异或,说明根本就求不出来,输出 I don't know.

2.为了应对I P V 这种直接赋值的做法,人为添加一个超级父节点T,v[T]=0每次让它跟T来异或,这样就不用特殊处理了

3.每次合并的时候,T一定要是父节点,特判一下。find的时候,进行路径压缩,同时对加权进行合并,通过异或偶数等于本身的特性,将底下的节点顺利的转化为父节点的子节点。

4.注意一下 !运算的优先级高于^,为了这个WA了几次,以后涉及位运算的,多写括号,感觉不是第一次被优先级给坑了。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = +;
int f[N],v[N];
int vis[N],a[];
int T=N-;
void init(int n)
{
for (int i=;i<=n+;i++){
f[i]=i;
v[i]=;
vis[i]=;
}
f[T]=T;
v[T]=;
}
int findset(int x)
{
if (x!=f[x]){
int tmp=f[x];
f[x]=findset(f[x]);
v[x]^=v[tmp];//因为v[x]本身就包括了异或上一层父节点的值,此时与上一层再异或一次,就抵消了
}
return f[x];
}
bool uset(int p,int q,int val)
{
int r1=findset(p);
int r2=findset(q);
if (r1==r2){
if ((v[p]^v[q])!=val) return ;
else return ;
}
if (r1==T) swap(r1,r2);
f[r1]=r2;
v[r1]=v[p]^v[q]^val;//这里要注意,实际V[r1]=xr1^xr2,而Vp和Vq包含这两项,并且用val把他们自身给抵消了,就剩下那两项了,异或确实是很奇妙
return ;
}
int main()
{
int n,Q,p,q,val,kase=;
char ch[];
char s[];
while(scanf("%d%d",&n,&Q))
{
if (!(n+Q)) break;
init(n);
printf("Case %d:\n",++kase);
bool err=;
int facts=;
for (int i=;i<=Q;i++){
scanf("%s",ch);
if (ch[]=='I'){
facts++;
gets(s);
if (sscanf(s,"%d%d%d",&p,&q,&val)==) {
val=q;q=T;
}
//cout<<p<<" "<<q<<" "<<val<<endl;
if (err) continue;
if (!uset(p,q,val)){
printf("The first %d facts are conflicting.\n",facts);
err=;
}
}
else {
int k,ans=;
scanf("%d",&k);
for (int i=;i<=k;i++){
scanf("%d",&a[i]);
if(err) continue;
int r=findset(a[i]);
ans^=v[a[i]];
a[i]=r;
vis[r]^=;
}
if (err) continue;
bool flag=;
for (int i=;i<=k;i++){
if (vis[a[i]]){//这里判断是否是奇数次
if (a[i]!=T){//如果奇数次是超级父节点,没关系,因为他的值已知
flag=;
}
vis[a[i]]=;
}
}
if (flag) printf("%d\n",ans);
else printf("I don't know.\n");
}
}
puts("");
}
return ;
}

UVALive 4487 Exclusive-OR 加权并查集神题的更多相关文章

  1. hdu 3047 Zjnu Stadium(加权并查集)2009 Multi-University Training Contest 14

    题意: 有一个运动场,运动场的坐席是环形的,有1~300共300列座位,每列按有无限个座位计算T_T. 输入: 有多组输入样例,每组样例首行包含两个正整数n, m.分别表示共有n个人,m次操作. 接下 ...

  2. hdu 3635 Dragon Balls(加权并查集)2010 ACM-ICPC Multi-University Training Contest(19)

    这道题说,在很久很久以前,有一个故事.故事的名字叫龙珠.后来,龙珠不知道出了什么问题,从7个变成了n个. 在悟空所在的国家里有n个城市,每个城市有1个龙珠,第i个城市有第i个龙珠. 然后,每经过一段时 ...

  3. HDU 3407.Zjnu Stadium 加权并查集

    Zjnu Stadium Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  4. A Bug's Life(加权并查集)

    Description Background  Professor Hopper is researching the sexual behavior of a rare species of bug ...

  5. A Bug's Life(加权并查集)

    Description Background Professor Hopper is researching the sexual behavior of a rare species of bugs ...

  6. P1196 银河英雄传说(加权并查集)

    P1196 银河英雄传说 题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在 ...

  7. Zjnu Stadium(加权并查集)

    Zjnu Stadium Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  8. 洛谷 P2024 [NOI2001]食物链(种类并查集,加权并查集)

    传送门 解题思路 加权并查集: 什么是加权并查集? 就是记录着每个节点到它的父亲的信息(权值等). 难点:在路径压缩和合并节点时把本节点到父亲的权值转化为到根节点的权值 怎么转化呢? 每道题都不一样Q ...

  9. 牛客网-Beauty of Trees 【加权并查集】

    锟斤拷锟接o拷https://www.nowcoder.com/acm/contest/119/A锟斤拷源锟斤拷牛锟斤拷锟斤拷 锟斤拷目锟斤拷锟斤拷 It锟斤拷s universally acknow ...

随机推荐

  1. 洛谷 P4287 [SHOI2011]双倍回文题解

    前言 用了一种很奇怪的方法来解,即二分判断回文,再进行某些奇怪的优化.因为这个方法很奇怪,所以希望如果有问题能够 hack 一下. 题解 我们发现,这题中要求的是字符串 \(SS'SS'\),其中 \ ...

  2. WireShark 之抓包QQ协议

  3. python matplotlib绘图大全(散点图、柱状图、饼图、极坐标图、热量图、三维图以及热图)

    //2019.7.14晚matplotlib七种常见图像输出编程大全 七种图形汇总输出如下: import numpy as np #导入数据结构nmupy模块import matplotlib.py ...

  4. ubuntu 中加速pip指令下载插件的速度

    在使用pip下载时很多时候下载速度特别慢,时不时就会发生timeout. 这是因为安装源与本机之间网络不畅导致,其实可以自己指定pip的下载来源,就像指定ubuntu更新源那样. 接下来谈谈步骤: 1 ...

  5. S7-300位逻辑指令仿真练习 停车场

    第三章 S7-300 指令应用 位逻辑指令 M存储器 在PLC中M存储区(也称位存储区,又称内部存储器标志位(M)存储器区),它属于系统存储区.在你选定具体的CPU型号后,可以查看CPU的技术规格,其 ...

  6. C# OBJ模型解析的封装(网上看到的保留一份)

    /// <author>Lukas Eibensteiner</author> /// <date>19.02.2013</date> /// < ...

  7. 洛谷 P2049 魔术棋子(vector)

    题目传送门 解题思路: 用一个vector维护每一个点都可以乘出哪些数来,然后将(n,m)的所有数从小到大输出即可. 要用一个bool ff[j][k]来维护当前这个点(i,j)里面有没有被放过k,以 ...

  8. Linux下部署开源版“禅道”项目管理系统《转载》

    Linux下部署开源版“禅道”项目管理系统 https://www.cnblogs.com/xxsl/p/6525378.html

  9. React 学习笔记(3) B站视频总结1

    视频地址 项目基础 react-cli // 项目结构 src │ App.js # 应用根组件 │ index.js # 入口js ├─api ├─assets ├─components ├─con ...

  10. css布局 -双飞翼布局&圣杯布局

    一,双飞翼布局 左右两边固定,中间可以随着浏览器放大和缩小 <!DOCTYPE html> <html lang="en"> <head> &l ...