Hdu 3234 XOR (weighted sum query set)
Zookeeper
There are n (n <= 20000) unknown integers X0, X1, X2Xn-1, there are the following Q (Q <= 40000) operations:
I p v: Tell you Xp = v
I p q v: Tell you Xp Xor Xq = v
Q k p1 p2... Pk: Ask Xp1 Xor Xp2 .. Xor Xpk, k is not greater than 15.
If the current I conflicts with the previous one
The idea is to query the expansion of the set. Each node represents the difference or value between the node and the root node .... Thoughts
Ps: I forgot to beat it. It took a long time for wa to get down.
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
Using namespace std; # define LL long const LL maxn = 20000 + 5; const ll inf = 1000000000; LL x [maxn]; LL pa [maxn], num [maxn], n; // num Array records the number of elements in each set void init () {// adds a xn, that is, zero node for (LL I = 0; I <= n; I ++) {pa [I] = I; x [I] = 0 ;}} LL find (LL id) {if (id! = Pa [id]) {LL tmp = pa [id]; LL root = find (pa [id]); x [id] ^ = x [tmp]; return pa [id] = root;} else return id;} bool unio (LL p, LL q, LL v) {LL pap = find (p ), paq = find (q); if (pap = paq) {return (x [p] ^ x [q]) = v; // pay attention to the order of operators, if no parentheses are added, the bitwise operation must be careful with the priority.} if (pap = n) swap (pap, paq); pa [pap] = paq; x [pap] = x [p] ^ x [q] ^ v; // the most important step is to connect the two trees, which is clever; return true ;} int main () {// freopen ("input.txt", "r", stdin); ll q, Kase = 1; while (scanf ("% lld", & n, & Q) & n) {init (); printf ("Case % lld: \ n ", kase ++); char cmd [2], str [20]; LL facts = 0; bool flag = true; for (LL I = 1; I <= Q; I ++) {if (! Flag) {gets (str); continue;} scanf ("% s", cmd); if (cmd [0] = 'I') {facts ++; gets (str); LL p, q, v; if (sscanf (str, "% lld", & p, & q, & v) = 2) {v = q; q = n;} if (! Unio (p, q, v) {printf ("The first % lld facts are conflicting. \ n ", facts); flag = false; continue ;}} else {LL k, idp [20], tag = 1; LL ans = 0; scanf ("% lld", & k); for (LL I = 0; I <k; I ++) {scanf ("% lld ", & idp [I]); num [find (idp [I])] = 0 ;}for (LL I = 0; I <k; I ++) {num [find (idp [I])] ++; ans ^ = x [idp [I] ;}for (LL I = 0; I <k; I ++) {if (num [find (idp [I])] % 2 = 1 & find (idp [I])! = N) {tag = 0; break;} if (! Tag) printf ("I don't know. \ n "); else printf (" % lld \ n ", ans) ;}} printf (" \ n ");} return 0 ;}