UVALive - 4487 HDU3234 UVA12232 【带权并查集】 非常好的一道题!!!
传送门
首先说下这道题真的是带权并查集中的神题, 做完这道题你会对带权并查集的理解更进一步, 比食物链那道题经典多了…. 所以不会带权并查集的建议先去学学后在做这道题…
题意: 这里有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 【带权并查集】 非常好的一道题!!!相关推荐
- hdu3234 Exclusive-OR(带权并查集)
题目 题目叙述来自思路来源,懒得敲了2333-- 思路来源 https://blog.csdn.net/XY20130630/article/details/50638922 题解 考虑,把Xp XO ...
- 【uva12232/hdu3461】带权并查集维护异或值
[uva12232/hdu3461]带权并查集维护异或值 题意: 对于n个数a[0]~a[n-1],但你不知道它们的值,通过逐步提供给你的信息,你的任务是根据这些信息回答问题: I P V :告诉你a ...
- hdu3234 带权并查集(XOR)
题意: 给你n个未知的正整数,有三总操作 I P V P的值是V I P Q V P XOR Q = V Q K ...
- HDU-3234 Exclusive-OR 异或带权并查集
题目描述 现在有n个数,X0,X1,-,Xn-1,你并不知道这n个数的大小,然后接下来有Q个询问,询问的格式如下 1) I p v, 告诉你 Xp = v 2) I p q v, 告诉你 Xp ^ X ...
- 2017乌鲁木齐区域赛I(带权并查集)
#include<bits/stdc++.h> using namespace std; int f[200010];//代表元 long long rl[200010];//记rl[i] ...
- BZOJ 2303 方格染色(带权并查集)
要使得每个2*2的矩形有奇数个红色,如果我们把红色记为1,蓝色记为0,那么我们得到了这2*2的矩形里的数字异或和为1. 对于每个方格则有a(i,j)^a(i-1,j)^a(i,j-1)^a(i-1,j ...
- POJ1703带权并查集(距离或者异或)
题意: 有两个黑社会帮派,有n个人,他们肯定属于两个帮派中的一个,然后有两种操作 1 D a b 给出a b 两个人不属于同一个帮派 2 A a b 问a b 两个人关系 输出 同一个帮派 ...
- POJ1988(带权并查集,搬砖块)
题意: 可以这样理解,有n快方形积木,一开始都是单独的放到哪,然后有两种操作 1 M a b 把a所在的那一堆落到b所在那一堆的上面(一开始自己是一堆) 2 C a 问a下面有多少个积木 ...
- LA3027简单带权并查集
题意: 有n个点,一开始大家都是独立的点,然后给出一些关系,a,b表示a是b的父亲节点,距离是abs(a-b)%1000,然后有一些询问,每次询问一个节点a到父亲节点的距离是多少? 思路: ...
- hdu4829 带权并查集(题目不错)
题意: Information Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
最新文章
- 深度解析JAVA动态代理设计模式
- shell 取中间行的第一列_shell脚本的使用该熟练起来了,你说呢?(篇三)
- Hadoop YARN安装部署初探
- C++11特性:override
- 尚硅谷最新版JavaWeb全套教程,java web零基础入门完整版(一)
- ES分组聚合:计算每个tag下的商品数量且某个filed包含指定关键字,分组,平均,每个tags下的平均价格,排序,指定范围区间
- java语言介绍 —(1)
- java map同步访问_同步 - Java synchronized块与Collections.synchronizedMap
- 实例--[QSerialPort]串口通信
- tensorflow python2迁移python3_tensorflow在python2和python3上的安装教程
- angularjs路由_AngularJS路由示例– ngRoute,$ routeProvider
- 嵌入式开发与C++开发的区别是什么?
- [学]《Python 核心编程》学习笔记(五)
- DELPHI2007 安装ACTIVEX插件的方法
- QQ自动登陆脚本生成器 v1.0
- Qt界面语言设置(官方汉化)
- ICML 2022 | 稀疏双下降:网络剪枝也能加剧模型过拟合?
- Matlab视觉处理模块定位控制全向轮小车运动:目标跟踪测试
- Learning to Predict Context-adaptiveConvolution for Semantic Segmentation阅读笔记
- []*T *[]T *[]*T 傻傻分不清楚