WuHan 2009 / UVa 12232 / HDU 3234 Exclusive-OR (异或的性质&加权并查集&合并时保持根结点不变)
2014-03-07 16:22
447 查看
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=3384
http://acm.hdu.edu.cn/showproblem.php?pid=3234
1. 对于第一种命令I p v,我们可以虚拟出一个点Xn = 0,那么p^Xn = v,故第一和第二种命令我们可以统一成p^q = v的模式。
2. 对于第三种命令,记val[i] = Xi^Xfa[i],那么Xp1^Xp2^...^Xpk = (val[Xp1]^...^val[Xpk]) ^ (Xfa[Xp1]^...^Xfa[Xpk])
val[Xp1]^...^val[Xpk]易求,对于Xfa[Xp1]^...^Xfa[Xpk],由于a^c^b^c = a^b,可先判断Xfa[Xpi]出现的次数的奇偶性,偶数不用管,奇数看Xfa[Xpi]是否为Xn,若不是则在Xp1^Xp2^...^Xpk中必有未知信息,若是则异或Xfa[Xpi]即可。
完整代码:
http://acm.hdu.edu.cn/showproblem.php?pid=3234
1. 对于第一种命令I p v,我们可以虚拟出一个点Xn = 0,那么p^Xn = v,故第一和第二种命令我们可以统一成p^q = v的模式。
2. 对于第三种命令,记val[i] = Xi^Xfa[i],那么Xp1^Xp2^...^Xpk = (val[Xp1]^...^val[Xpk]) ^ (Xfa[Xp1]^...^Xfa[Xpk])
val[Xp1]^...^val[Xpk]易求,对于Xfa[Xp1]^...^Xfa[Xpk],由于a^c^b^c = a^b,可先判断Xfa[Xpi]出现的次数的奇偶性,偶数不用管,奇数看Xfa[Xpi]是否为Xn,若不是则在Xp1^Xp2^...^Xpk中必有未知信息,若是则异或Xfa[Xpi]即可。
完整代码:
/*0.102s*/ #include<bits/stdc++.h> using namespace std; const int mx = 20005; int val[mx], fa[mx], n; char str[100]; int find(int x) { if (~fa[x]) { int tmp = fa[x]; fa[x] = find(fa[x]); val[x] ^= val[tmp]; ///pushdown return fa[x]; } return x; } bool merge(int x, int y, int v) { int fx = find(x), fy = find(y); if (fx == fy) return (val[x] ^ val[y]) == v; if (fx == n) swap(fx , fy); ///技巧:始终使得Xn(虚拟的点)为根结点 fa[fx] = fy, val[fx] = val[x] ^ v ^ val[y]; return true; } int main() { //freopen("in.txt", "r", stdin); int m, p, q, v, k, x, ans, cas = 0, facts; bool isError; map<int, int> mp; map<int, int>::iterator iter; while (scanf("%d%d", &n, &m), n) { getchar(); printf("Case %d:\n" , ++cas); memset(val, 0, sizeof(val)); memset(fa, -1, sizeof(fa)); facts = 0; isError = false; while (m--) { if (getchar() == 'I') { gets(str); ++facts; if (isError) continue; if (sscanf(str, "%d%d%d", &p, &q, &v) == 2) v = q, q = n; ///换成根结点 if (!merge(p, q, v)) { isError = true; printf("The first %d facts are conflicting.\n" , facts++); } } else { scanf("%d", &k); ans = 0; mp.clear(); while (k--) { scanf("%d", &x); if (isError) continue; find(x); ///更新一下值再计算 ans ^= val[x]; ++mp[find(x)]; } getchar(); if (isError) continue; for (iter = mp.begin(); iter != mp.end(); ++iter) { if (iter->second & 1) { if (iter->first != n) break; ///存在未知信息 else ans ^= val[iter->first]; } } if (iter == mp.end()) printf("%d\n" , ans); else puts("I don't know."); } } putchar(10); } return 0; }
相关文章推荐
- Hdu 3234 & Uva 12232 Exclusive-OR
- uva 12232 - Exclusive-OR(加权并查集)
- 异或(Exclusive-OR,Wuhan 2009,LA 4487)
- uva12232 - Exclusive-OR 加权并查集
- HDU 3234 | UValive 4487 - Exclusive-OR (加权并查集)
- UVa 11987 Almost Union-Find (加权并查集&删除结点的技巧)
- UVa - 12232 - Exclusive-OR
- HDU 3234 Exclusive-OR(加权并差集)
- POJ 1703 Find them, Catch them (并查集&利用异或的性质优化)
- UVALIVE 4487 Exclusive-OR(加权并查集)
- UVALive 4487 Exclusive-OR 加权并查集神题
- UVA 12232 - Exclusive-OR(带权并查集)
- UVA - 12232 Exclusive-OR (并查集扩展偏离向量)
- UVA 12232 Exclusive-OR (带权值的并查集)
- UVA 12232 - Exclusive-OR(带权并查集)
- UVA 12232 Exclusive-OR(并查集+思想)
- uva 12232 Exclusive-OR
- UVA - 12232 Exclusive-OR (并查集扩展偏离向量)
- UVA 12232 Exclusive-OR(并查集+思想)
- 带权并查集--uva12232 Exclusive-OR