Question: give N numbers and some conditions, x [I] = v or x [I] ^ x [j] = k, and then give some inquiries, x [a1] ^ x [a2]……
Http://acm.hdu.edu.cn/showproblem.php? Pid = 1, 3234
Classic query set
Similar to many questions, record the relationship between a node and the root node, that is, the difference or value with the root node.
If pre [a] = ra, pre [B] = rb; then what is the situation after merging, that is, r [a] = num [a] ^ num [ra]; r [B] = num [B] ^ num [rb]; Because r [a] ^ r [B] = c
Now the requirement is num [ra] = num [ra] ^ num [rb] = r [a] ^ r [B] ^ c;
There is no problem with merging, but there is another problem: there are two conditions given. What should we do if it is just a single node?
Add a redundant node. The label is n, the value is 0, and any number and 0 are different or are themselves.
The rest is the query. If a certain number of queries exist in a collection.
If the root node is the redundant node that we add, it is clear that r [x] = num [x] can be used to directly or differently.
If it is not a redundant node and r [x] = r [x] ^ r [pre [x], the root node is exclusive or one time. If the number of a set is an even number, if the root number is an odd number, it cannot be judged.
[Cpp]
# Include <iostream>
# Include <cstdio>
# Include <map>
# Include <cstring>
# Include <cmath>
# Include <vector>
# Include <algorithm>
# Include <set>
# Include <string>
# Include <queue>
# Define inf 1 <30
# Define M 60005
# Define N 20005
# Define maxn300005
# Define eps 1e-10
# Define zero (a) fabs (a) <eps
# Define Min (a, B) (a) <(B )? (A) (B ))
# Define Max (a, B) (a)> (B )? (A) (B ))
# Define pb (a) push_back ()
# Define mp (a, B) make_pair (a, B)
# Define mem (a, B) memset (a, B, sizeof ())
# Define LL long
# Define lson step <1
# Define rson step <1 | 1
# Define MOD 1000000009.
# Define sqr (a) * ())
Using namespace std;
Int pre [N], r [N];
Int n, q;
Int K, num [N];
Char ope [1000];
Vector <int> que;
Void Init ()
{
For (int I = 0; I <= n; I ++) pre [I] = I, r [I] = 0;
}
Int find (int x)
{
If (x! = Pre [x])
{
Int f = pre [x];
Pre [x] = find (pre [x]);
R [x] ^ = r [f];
}
Return pre [x];
}
Bool Union (int a, int B, int c)
{
Int ra = find (a), rb = find (B );
If (ra = rb)
{
If (r [a] ^ r [B])! = C) return false;
Else return true;
}
If (ra = n) swap (ra, rb); // This sentence is very important. It is related to the Query judgment and WA several times.
Pre [ra] = rb;
R [ra] = r [a] ^ r [B] ^ c;
Return true;
}
Int Query ()
{
Bool vis [N]; mem (vis, false );
Int ans = 0;
For (int I = 0; I <K; I ++)
{
If (vis [I]) continue;
Int cnt = 0;
Int root = find (num [I]);
For (int j = I; j <K; j ++)
{
If (! Vis [j] & find (num [j]) = root)
{
Cnt ++;
Vis [j] = true;
Ans ^ = r [num [j];
}
}
If (root! = N & cnt & 1) return-1;
}
Return ans;
}
Int main ()
{
Int CAS = 0;
While (scanf ("% d", & n, & q )! = EOF)
{
If (n = 0 & q = 0) break;
Printf ("Case % d: \ n", ++ CAS );
Init ();
Bool error = false;
Int cas = 0;
While (q --)
{
Scanf ("% s", ope );
If (ope [0] = 'I ')
{
Getchar (); gets (ope); cas ++;
Int space = 0, u, v, w;
For (int I = 0; I <strlen (ope); I ++) space = space + (ope [I] = '');
If (space = 1) {sscanf (ope, "% d", & u, & w); v = n ;}
Else sscanf (ope, "% d", & u, & v, & w );
If (error) continue;
If (! Union (u, v, w) {printf ("The first % d facts are conflicting. \ n", cas); error = true ;}
}
Else
{
Scanf ("% d", & K );
For (int I = 0; I <K; I ++) scanf ("% d", & num [I]);
If (error) continue;
Int ans = Query ();
If (ans =-1) puts ("I don't know .");
Else printf ("% d \ n", ans );
}
}
Puts ("");
}
Return 0;
}
# Include <iostream>
# Include <cstdio>
# Include <map>
# Include <cstring>
# Include <cmath>
# Include <vector>
# Include <algorithm>
# Include <set>
# Include <string>
# Include <queue>
# Define inf 1 <30
# Define M 60005
# Define N 20005
# Define maxn300005
# Define eps 1e-10
# Define zero (a) fabs (a) <eps
# Define Min (a, B) (a) <(B )? (A) (B ))
# Define Max (a, B) (a)> (B )? (A) (B ))
# Define pb (a) push_back ()
# Define mp (a, B) make_pair (a, B)
# Define mem (a, B) memset (a, B, sizeof ())
# Define LL long
# Define lson step <1
# Define rson step <1 | 1
# Define MOD 1000000009.
# Define sqr (a) * ())
Using namespace std;
Int pre [N], r [N];
Int n, q;
Int K, num [N];
Char ope [1000];
Vector <int> que;
Void Init ()
{
For (int I = 0; I <= n; I ++) pre [I] = I, r [I] = 0;
}
Int find (int x)
{
If (x! = Pre [x])
{
Int f = pre [x];
Pre [x] = find (pre [x]);
R [x] ^ = r [f];
}
Return pre [x];
}
Bool Union (int a, int B, int c)
{
Int ra = find (a), rb = find (B );
If (ra = rb)
{
If (r [a] ^ r [B])! = C) return false;
Else return true;
}
If (ra = n) swap (ra, rb); // This sentence is very important. It is related to the Query judgment and WA several times.
Pre [ra] = rb;
R [ra] = r [a] ^ r [B] ^ c;
Return true;
}
Int Query ()
{
Bool vis [N]; mem (vis, false );
Int ans = 0;
For (int I = 0; I <K; I ++)
{
If (vis [I]) continue;
Int cnt = 0;
Int root = find (num [I]);
For (int j = I; j <K; j ++)
{
If (! Vis [j] & find (num [j]) = root)
{
Cnt ++;
Vis [j] = true;
Ans ^ = r [num [j];
}
}
If (root! = N & cnt & 1) return-1;
}
Return ans;
}
Int main ()
{
Int CAS = 0;
While (scanf ("% d", & n, & q )! = EOF)
{
If (n = 0 & q = 0) break;
Printf ("Case % d: \ n", ++ CAS );
Init ();
Bool error = false;
Int cas = 0;
While (q --)
{
Scanf ("% s", ope );
If (ope [0] = 'I ')
{
Getchar (); gets (ope); cas ++;
Int space = 0, u, v, w;
For (int I = 0; I <strlen (ope); I ++) space = space + (ope [I] = '');
If (space = 1) {sscanf (ope, "% d", & u, & w); v = n ;}
Else sscanf (ope, "% d", & u, & v, & w );
If (error) continue;
If (! Union (u, v, w) {printf ("The first % d facts are conflicting. \ n", cas); error = true ;}
}
Else
{
Scanf ("% d", & K );
For (int I = 0; I <K; I ++) scanf ("% d", & num [I]);
If (error) continue;
Int ans = Query ();
If (ans =-1) puts ("I don't know .");
Else printf ("% d \ n", ans );
}
}
Puts ("");
}
Return 0;
}