传送门
首先说下这道题真的是带权并查集中的神题, 做完这道题你会对带权并查集的理解更进一步, 比食物链那道题经典多了…. 所以不会带权并查集的建议先去学学后在做这道题…

题意: 这里有n个数a0, …., an-1, 但是你不知道它们具体的值, 接下来会给你一些信息和询问,
I p v 表示信息a[p] = v;
I p q v 表示a[p] ^ a[q] = v;
Q k p1 p2 …. pk, 你需要输出p1 ^ p2 ^ ….. ^ pk 的值是多少, 如果不知道输出”I don’t know.”, 还要注意的是给出的信息可能是冲突的, 所以如果前面的某几个信息已经冲突了, 输出此时冲突的信息是第几个, 然后剩下的所有操作都不用管…

思路: 首先很明显的要用带权并查集维护好这个信息关系, 所以r[v] 代表v和其根节点的异或值是多少, 注意异或的特性, a ^ a ^ b = b, 先说压缩路径的处理, 假设连接关系是a -> b -> c, 我们现在要把a -> c, 即把a压到c去, 所以此时r[a] 应该变化为a ^ c的值, 那么怎么处理了, 实际上就是r[a] ^= a[b], 首先假设w[i] 表示 a[i] 这个数字的具体值, 那么r[a] = w[a] ^ w[b], r[b] = w[b] ^ w[c], 所以w[a] ^ w[c] = w[a] ^ w[b] ^ w[b] ^ w[c], 也就是r[a] ^ r[b], 压缩路径解决了… 然后每次的信息第二种类型实际上就是给出了r[v] 的值, 这道题最难的点也是最好的点在于第一种信息的处理…, 此时我们需要虚拟一个点t, 且w[t] = 0, 那么知道第一种信息的点就可以直接和t进行合并相连. 和t相连的点v此时的r[v] = w[v].

fapi 表示pi的根节点.
对于询问: 我们可以发现w[p1] ^ … ^ w[pk] = r[p1] ^ fap1 ^ …. ^ r[pk] ^ fapn, 那么如果某点的根节点是虚拟点t, 那么就可以不用加进去, 因为w[t] = 0, w[i] = r[i], 所以要想知道上式的值只有一个方法就是他们的根节点成对出现, 可以相互抵消, 因为我们不能知道单个点w[i]的确定值, 只能通过消除的方式. 所以我们求出这些点的根节点,判断他们的数量是否都是偶数就行了.

注: 和虚拟点进行合并相连时要知道也在压缩路径, 并且如果对于某条链上的某个点确定的值知道了, 那么总这个点到根节点的所有值就都知道了. 也就是全部都会跟虚拟点进行相连….. 注意想清楚这里.

AC Code

const int maxn = 2e4+5;
int fa[maxn], r[maxn];
int n;
void init() {for (int i = 0 ; i <= n ; i ++) {fa[i] = i;r[i] = 0;}
}
int Find(int x) {if (fa[x] == x) return x;else {int tmp = fa[x];fa[x] = Find(fa[x]);r[x] ^= r[tmp];return fa[x];}
}
bool Un(int x, int y, int s) {int fx = Find(x);int fy = Find(y);if (fx == fy) {if ((r[x] ^ r[y]) != s) return false;return true;}if (fx == n) swap(fx, fy); // 保证虚拟节点为优先点.fa[fx] = fy;r[fx] = r[x] ^ r[y] ^ s;// 不理解为哈像上面这样写的.// 想清楚压缩完路径后r值意义的变化和进来的信息.return true;
}
vector<int>ve;
int a[maxn], vis[maxn];
int cas = 1;
void solve()
{int q, fac, flag;while(~scanf("%d%d", &n, &q) && (n || q)) {init(); fac = 0; flag = 0;printf("Case %d:\n", cas++);for (int i = 1 ; i <= q ; i ++) {string op;cin >> op;if (op[0] == 'I') {int u, v, w;if (!flag) ++ fac;char str[10];scanf("%d%d", &u, &v);char ch; ch = getchar();if (ch == ' ') {scanf("%d", &w);if (flag) continue;if (!Un(u, v, w)) {flag = 1;printf("The first %d facts are conflicting.\n", fac);}}else {if (flag) continue;if (!Un(u, n, v)) {flag = 1;printf("The first %d facts are conflicting.\n", fac);}}}else {int k; scanf("%d", &k);ve.clear(); int ans = 0; Fill(vis, 0);for (int j = 1 ; j <= k ; j ++) {scanf("%d", a+j);if (flag) continue;int f = Find(a[j]);ans ^= r[a[j]];  // 这个顺序必须在压缩路径之后进行!// 因为此时有可能r[a[j] 的值是已知的但是还没更新过来// 只是单纯的其根节点和t连接了, 所以这里相当于更新一次r值.// 这是个很大的坑点.if (f != n) {ve.pb(f);++vis[f];}}if (flag) continue;int ff = 1;for (int j = 0 ; j < sz(ve) ; j ++) {if (vis[ve[j]] & 1) {ff = 0;break;}}if (ff) printf("%d\n", ans);else printf("I don't know.\n");}}printf("\n");}
}

UVALive - 4487 HDU3234 UVA12232 【带权并查集】 非常好的一道题!!!相关推荐

  1. hdu3234 Exclusive-OR(带权并查集)

    题目 题目叙述来自思路来源,懒得敲了2333-- 思路来源 https://blog.csdn.net/XY20130630/article/details/50638922 题解 考虑,把Xp XO ...

  2. 【uva12232/hdu3461】带权并查集维护异或值

    [uva12232/hdu3461]带权并查集维护异或值 题意: 对于n个数a[0]~a[n-1],但你不知道它们的值,通过逐步提供给你的信息,你的任务是根据这些信息回答问题: I P V :告诉你a ...

  3. hdu3234 带权并查集(XOR)

    题意:       给你n个未知的正整数,有三总操作       I P V            P的值是V       I P Q V          P XOR Q = V       Q K ...

  4. HDU-3234 Exclusive-OR 异或带权并查集

    题目描述 现在有n个数,X0,X1,-,Xn-1,你并不知道这n个数的大小,然后接下来有Q个询问,询问的格式如下 1) I p v, 告诉你 Xp = v 2) I p q v, 告诉你 Xp ^ X ...

  5. 2017乌鲁木齐区域赛I(带权并查集)

    #include<bits/stdc++.h> using namespace std; int f[200010];//代表元 long long rl[200010];//记rl[i] ...

  6. BZOJ 2303 方格染色(带权并查集)

    要使得每个2*2的矩形有奇数个红色,如果我们把红色记为1,蓝色记为0,那么我们得到了这2*2的矩形里的数字异或和为1. 对于每个方格则有a(i,j)^a(i-1,j)^a(i,j-1)^a(i-1,j ...

  7. POJ1703带权并查集(距离或者异或)

    题意:       有两个黑社会帮派,有n个人,他们肯定属于两个帮派中的一个,然后有两种操作 1 D a b 给出a b 两个人不属于同一个帮派 2 A a b 问a b 两个人关系 输出 同一个帮派 ...

  8. POJ1988(带权并查集,搬砖块)

    题意:        可以这样理解,有n快方形积木,一开始都是单独的放到哪,然后有两种操作 1 M a b 把a所在的那一堆落到b所在那一堆的上面(一开始自己是一堆) 2 C a 问a下面有多少个积木 ...

  9. LA3027简单带权并查集

    题意:       有n个点,一开始大家都是独立的点,然后给出一些关系,a,b表示a是b的父亲节点,距离是abs(a-b)%1000,然后有一些询问,每次询问一个节点a到父亲节点的距离是多少? 思路: ...

  10. hdu4829 带权并查集(题目不错)

    题意: Information Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...

最新文章

  1. 深度解析JAVA动态代理设计模式
  2. shell 取中间行的第一列_shell脚本的使用该熟练起来了,你说呢?(篇三)
  3. Hadoop YARN安装部署初探
  4. C++11特性:override
  5. 尚硅谷最新版JavaWeb全套教程,java web零基础入门完整版(一)
  6. ES分组聚合:计算每个tag下的商品数量且某个filed包含指定关键字,分组,平均,每个tags下的平均价格,排序,指定范围区间
  7. java语言介绍 —(1)
  8. java map同步访问_同步 - Java synchronized块与Collections.synchronizedMap
  9. 实例--[QSerialPort]串口通信
  10. tensorflow python2迁移python3_tensorflow在python2和python3上的安装教程
  11. angularjs路由_AngularJS路由示例– ngRoute,$ routeProvider
  12. 嵌入式开发与C++开发的区别是什么?
  13. [学]《Python 核心编程》学习笔记(五)
  14. DELPHI2007 安装ACTIVEX插件的方法
  15. QQ自动登陆脚本生成器 v1.0
  16. Qt界面语言设置(官方汉化)
  17. ICML 2022 | 稀疏双下降:网络剪枝也能加剧模型过拟合?
  18. Matlab视觉处理模块定位控制全向轮小车运动:目标跟踪测试
  19. Learning to Predict Context-adaptiveConvolution for Semantic Segmentation阅读笔记
  20. []*T *[]T *[]*T 傻傻分不清楚

热门文章

  1. M-02-12.[紫猫]Url网络操作扩展
  2. 笔记本计算机风扇连线,机箱风扇接口怎么接电源线【图文】
  3. 语音合成IC与语音IC的两三事
  4. 给大家分享【CDR基础教程】
  5. 梦参老和尚:糊涂人念〈大悲咒〉往生的故事
  6. SPSS如何计算方差膨胀因子
  7. BGA返修台使用说明
  8. javascript调用php函数_JavaScript怎么调用PHP函数?
  9. java long转float_Java中为什么long能自动转换成float类型
  10. 3DMax与Unity统一长度单位和轴