Q k q1q2... Qk: Q1? Q2 ...? Qk
If the Q operation cannot be determined, output "I don't know ."
For I operation conflicts, the output is the number of I operations that conflict, and all subsequent operations are stopped.Solution: weighted and query set. f [x] indicates the Father's Day of x node, and d [x] indicates the value or value of x node and its parent node. For the determined node value, we can set the Father's Day to 0. In this case, we should pay attention when performing the merge operation. If the Father's Day is 0, it is necessary to point a node to 0 (that is to say, 0 nodes cannot have Father's Day points). First, the value is determined in the UNICOM set pointing to 0 nodes, the query requires special judgment, and the second is convenient for processing when performing the first operation.
During the query, all the numbers must be divided into Unicom sets. If the number of Unicom sets is odd and the root node is not 0, the value cannot be determined, otherwise, the sum of the values or values of all nodes and Father's Day points is enough.
#include
#include
#include using namespace std;const int maxn = 20005;const int maxm = 105;bool flag;int N, Q, f[maxn], d[maxn];int getfar (int x) { if (x == f[x]) return x; int tmp = f[x]; f[x] = getfar(f[x]); d[x] ^= d[tmp]; return f[x];}void query () { int n, ret = 0, num[maxm], vis[maxm]; memset(vis, 0, sizeof(vis)); scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", &num[i]); num[i]++; } if (flag) return; for (int i = 0; i < n; i++) { int root = getfar(num[i]), cnt = 1; if (root == 0 || vis[i]) continue; for (int j = i+1; j < n; j++) { if (getfar(num[j]) == root) { cnt++; vis[j] = 1; } } if (cnt&1) { printf("I don't know.\n"); return ; } } for (int i = 0; i < n; i++) ret ^= d[num[i]]; printf("%d\n", ret);}bool link () { char s[maxm]; gets(s); int u, v, k; int type = sscanf(s, "%d%d%d", &u, &v, &k); u++; if (type == 2) { k = v; v = 0; } else v++; int p = getfar(u); int q = getfar(v); if (p == 0) swap(p, q); if (p != q) { f[p] = q; d[p] = d[u]^d[v]^k; } else return (d[u]^d[v]) != k; return false;}int main () { int cas = 1; while (~scanf("%d%d", &N, &Q) && N) { printf("Case %d:\n", cas++); flag = false; memset(d, 0, sizeof(d)); for (int i = 0; i <= N; i++) f[i] = i; int ti = 0, u, v; char s[maxm]; for (int i = 0; i < Q; i++) { scanf("%s", s); if (s[0] == 'I') { ti++; if (link()) { flag = true; printf("The first %d facts are conflicting.\n", ti); } } else if (s[0] == 'Q') query(); } printf("\n"); } return 0;}