题意: 有N个数X[0] ~ X[N], 事先并不知道他们的值,有三种操作(^为异或):

I P V :告诉你X[P] = V
I P Q V:告诉你X[P] ^ X[Q] = V
Q K P1..PK:询问X[P1]^X[P2]^...X[PK]的值

如果信息矛盾 或者 不能知道查询的结果输出一些提示信息。

思路:对于第一种操作, X[P] = V 可以看做第二种操作的 X[P] ^ 0 = V, 新增一个节点n, 他的值为0。

对于查询, 我们知道, 如果有a ^ b = x1, b ^ c = x2, 可以得出 a ^ c = x1 ^ x2, 那么如果Xa ^ Xb = v为a, b连接一条边,权值为v,则a^b能求出结果的条件是a, b有相同的根节点,这里可以使用并查集, 注意在合并的时候需要进行路径压缩, 即每一节点有一个与根节点异或的值。那么在查询的时候, 先把不同集合里面的节点分开, 相同集合里面的节点放一起, 在同一个集合里面, 如果根节点是n, 那么一定可以得出所有节点的异或值, 如果不为n, 那么只要出现节点个数为奇数的集合就不能得出结果, 否则将每个节点的值异或起来即可。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<iostream>
#include<algorithm>
const int maxn = 2e4 + 10;
using namespace std;int n, Q;
char cmd[maxn];
int pa[maxn], dis[maxn];int num, r[50], fac;
int read() {int len = strlen(cmd);num = 0;for(int i = 0; i < len; i++) {if(cmd[i] < '0' || cmd[i] > '9') continue;int j = i, sum = 0;while(j < len && cmd[j] >= '0' && cmd[j] <= '9') {sum = sum * 10 + cmd[j] - '0';j++;}r[num++] = sum;i = j;}char ch = cmd[0];if(ch == 'Q') return 3;fac++;if(num == 2) return 1;return 2;
}int findset(int x) {if(x == pa[x]) return x;int px = findset(pa[x]);dis[x] ^= dis[pa[x]];return pa[x] = px;
}bool can_unit(int x, int y, int val) {int nx = findset(x), ny = findset(y);if(nx == ny && (dis[x] ^ dis[y]) != val) return false;if(nx == ny) return true;if(nx == n + 1) {pa[ny] = nx;dis[ny] = dis[x] ^ dis[y] ^ val;} else {pa[nx] = ny;dis[nx] = dis[x] ^ dis[y] ^ val;}return true;
}vector<int> G[50];
int fa[50];int main() {int kase = 1;while(scanf("%d %d", &n, &Q) && n) {fac = 0;for(int i = 0; i <= n + 2; i++) {pa[i] = i; dis[i] = 0;}gets(cmd);bool ans = true;printf("Case %d:\n", kase++);while(Q--) {gets(cmd);if(!ans) continue;int op = read();if(op == 1) {int p = r[0], v = r[1];if(!can_unit(p, n + 1, v)) { ans = false; printf("The first %d facts are conflicting.\n", fac); }} else if(op == 2) {int p = r[0], q = r[1], v = r[2];if(!can_unit(p, q, v)) { ans = false; printf("The first %d facts are conflicting.\n", fac); }} else {int x = 0;for(int i = 0; i < 20; i++) G[i].clear();for(int i = 1; i < num; i++) {int id = r[i], nx = findset(id);bool have = false;for(int j = 0; j < x; j++) {if(fa[j] != nx) continue;have = true;G[j].push_back(id);break;}if(have) continue;G[x].push_back(id); fa[x] = nx;x++;}bool solve = true;int res = 0;for(int i = 0; i < x; i++) {if(fa[i] != n + 1 && G[i].size() % 2 == 1) { solve = false; break; }for(int j = 0; j < G[i].size(); j++) {int k = G[i][j];res ^= dis[k];}}if(!solve) printf("I don't know.\n");else printf("%d\n", res);}}printf("\n");}return 0;
}

LA4487 Exclusive-OR (加权并查集)相关推荐

  1. Rochambeau POJ - 2912 (枚举和加权并查集+路径压缩)找唯一裁判

    题意:有n个人玩石头剪刀布,有且只有一个裁判.除了裁判每个人的出拳形式都是一样的. a<b表示b打败a,a=b表示a和b出拳一样,平手.a>b表示a打败b. 给出m个回合的游戏结果,问能否 ...

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

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

  3. A Bug‘s Life POJ 2492 加权并查集

    A Bug's Life POJ 2492 加权并查集 传送门:http://poj.org/problem?id=2492 Description Background Professor Hopp ...

  4. 【加权并查集】bzoj 4602 齿轮

    立志用最少的代码做最高效的表达 Description 现有一个传动系统,包含了N个组合齿轮和M个链条.每一个链条连接了两个组合齿轮u和v,并提供了一个传动比x : y.即如果只考虑这两个组合齿轮,编 ...

  5. Zjnu Stadium HDU - 304 加权并查集

    题意: 观众席围成一圈.列的总数是300,编号为1–300,顺时针计数,我们假设行的数量是无限的.将有N个人去那里.他对这些座位提出了要求:这意味着编号A的顺时针X距离坐着编号B.例如:A在第4列,X ...

  6. bzoj 3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦(加权并查集)

    3362: [Usaco2004 Feb]Navigation Nightmare 导航噩梦 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 121  ...

  7. 【并查集】noi2001食物链

    P2024 [NOI2001]食物链 //这是一道比我年纪大的题啊啊啊啊啊QAQ 加权并查集  三倍并查集好厉害qwq 图源洛谷题解 贴代码qwq 1 #include<cstdio> 2 ...

  8. 【高级数据结构其一·并查集】

    用于快速处理不相交集合的查询和合并问题 经典应用:连通子图,最小生成树Kruskal,最近公共祖先 #初始化 n=int(input()) s=[i for i in range(n+1)]#查询 d ...

  9. 并查集(加权规则、折叠规则)

    1.基本知识概念 等价类与并查集.如果用符号"="表示集合上的等价关系,那么对于该集合中的任意对象x,y,z,下列性质成立 : 自反性:x=x(即等于自身) 对称性:若x=y,则y ...

  10. poj1182(加权值的并查集)

    Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A.  现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它 ...

最新文章

  1. 随机挑选分类训练集和测试集
  2. 区块链论文9 FlyClient-加密货币的超轻客户端
  3. C++拷贝构造函数的参数为什么必须使用引用类型(无限递归)
  4. HSmartWindowControl 之 摄像头实时显示( 使用 WPF )
  5. python 数学基础_Python3数学基础 - 随笔分类 - 既生喻何生亮 - 博客园
  6. Handler.postDelayed(new Runnable)是否运行在主线程
  7. Sqoop-MySQL导入hive时id为文本解决
  8. 电力物联网智慧路灯充电桩传感器技术应用方案
  9. Keil MDK下载程序时的相关设置
  10. HEXO+Github,搭建属于自己的博客
  11. javascript原生代码取单选框的值
  12. oracle:sql介绍及SQL基本查询 lt;四gt;
  13. OpenGL ES 3.1 Android扩展包介绍
  14. 求1加到n的发散思维方法
  15. 女朋友生日java程序_★★女朋友要过生日了!我想用java为她写一个程序,一举两得啊! 希望大家多提建议啊!谢谢!!!...
  16. python如何采集同花顺股票日度历史数据
  17. 数字电路硬件设计系列(二)之DC-DC电源设计
  18. 2019年6月18号 AndroidStudio+夜神模拟器 搭建Xposed环境
  19. JavaWeb-狂神-P11
  20. C/C++编译器并行优化技术:并行优化针对多核处理器和多线程环境进行优化,以提高程序的并行度

热门文章

  1. Spire.Cloud 在线协同编辑Word文档
  2. CDR插件开发之Addon插件006 - 初体验:通过C#代码用外挂方式操作CDR中的对象
  3. Django 个人博客网站+simpleui后台
  4. 从零開始搭建微信硬件开发环境全过程——1小时掌握微信硬件开发流程
  5. 精灵球Plus使用方法
  6. 扫描无法传送到计算机,文件无法从复印机扫描到电脑?可能是以下操作您没有注意到...
  7. 鼠标右键新建没有.txt文本文档
  8. unity3d之计算两向量的旋转角
  9. java代码实现一个月内不再提醒,通用到期问题
  10. 看完知乎轮子哥的编程之路,我只想说,收下我的膝盖。。。