ntoj 1046 [NSCFXI]世界树
题目描述
世界的基本规律就是“负负得正”,也就是说,这个世界是到处在进行异或(XOR)运算的世界。现在有 N 个非负整数,并且它们的值不会发生变化。但是你并不知道它们究竟是那些数字。我们会给你一些事实,同时给出一些询问需要你进行处理。
有两种事实和一种询问:
I p v——表明第 p 个数的值是 v。
I p q v——表明第 p 个数和第 q 个数的异或值是 v。
Q k p1 p2 p3 … pk——求第 p1, p2, p3, … pk 个数的异或值。
注意,这 N 个数是从 0 开始编号的。输入
输入文件包含多组测试数据。
每组测试数据的第一行包括两个整数 N, Q,分别表示数的个数和操作的数目。
之后 Q 行,每行一个如题目描述中所述的操作。
输入文件的最后一行包含两个 0,表示输入文件的终止。输出
对于每个测试数据,在第一行输出“Case k:”,其中 k 表示测试数据的编号。
测试数据从 1 开始编号。
对于第 i 个事实(不计数询问),如果它与前面的事实有冲突,输出“The first i facts are conflicting.”,并且在这个测试数据中不要再输出任何内容。
对于每个询问,如果还没有出现冲突的事实,输出询问的结果。如果询问的结果不能被确定,输出“I don't know.”。
在每个测试数据的输出结束之后额外输出一个空行。提示
测试数据保证最多 10 组。
对于所有的数据满足 1≤N≤20000,1≤Q≤40000。询问中的 k≤15,事实中的 v≤220。
保证有部分小数据。
类似于ural 1003
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5 + 10; 4 5 int fa[N], dis[N], n, q, a[20], T = N - 1, vis[N]; 6 7 char inp[N]; 8 9 int get(int x) { 10 if(fa[x] == x) return x; 11 int f = get(fa[x]); 12 dis[x] ^= dis[fa[x]]; 13 return fa[x] = f; 14 } 15 16 int merge(int x, int y, int v) { 17 int fx = get(x), fy = get(y); 18 if(fx == fy) return (dis[x] ^ dis[y]) == v; 19 if(fx == T) swap(fx, fy); 20 fa[fx] = fy; 21 dis[fx] = dis[x] ^ dis[y] ^ v; 22 return 1; 23 } 24 25 void sol() { 26 bool flag = 0; 27 for(int i = 0 ; i <= n ; ++ i) fa[i] = i, dis[i] = 0; 28 fa[T] = T, dis[T] = 0; 29 for(int i = 1, factot = 0 ; i <= q ; ++ i) { 30 char op[10]; scanf("%s", op); 31 if(op[0] == 'I') { 32 ++ factot; 33 gets(inp); 34 int p, q, v; 35 if(sscanf(inp, "%d%d%d", &p, &q, &v) == 2) v = q, q = T; 36 if(flag) continue; 37 if(!merge(p, q, v)) flag = 1, printf("The first %d facts are conflicting.\n", factot); 38 } else { 39 int k; scanf("%d", &k); 40 for(int j = 1 ; j <= k ; ++ j) scanf("%d", &a[j]); 41 42 if(flag) continue; 43 int check = 1, ans = 0; 44 for(int j = 1 ; j <= k ; ++ j) { 45 int x = a[j]; 46 a[j] = get(x); 47 vis[a[j]] ^= 1; 48 ans ^= dis[x]; 49 } 50 for(int j = 1 ; j <= k ; ++ j) { 51 if(vis[a[j]] && a[j] != T) { 52 check = 0; 53 } 54 vis[a[j]] = 0; 55 } 56 if(check) printf("%d\n", ans); 57 else puts("I don't know."); 58 } 59 } 60 } 61 62 int main() { 63 int T = 0; 64 while(scanf("%d%d", &n, &q) && !(!n && !q)) { 65 printf("Case %d:\n", ++ T); 66 sol(); 67 puts(""); 68 } 69 }