该死的期末复习终于结束了。。。
暑 假 来 了 \color{#ff0000}{暑假来了} 暑假来了!!!
所以我就珂以非常开心的写博客了。
原题链接:
hdu
题意简述
多组数据。你有一个没有确定的数列。有一些操作,格式:
I p v
第 p p p个是 v v v(如果某个位置有很多个值,就是矛盾的)
I p q v
(没错也是I,所以要用sscanf判一下空格数量)第 p p p个异或第 q q q个为 v v v(这个异或值也可能会有矛盾)
Q k p1 p2 ... pk
求 p 1 , p 2... p k p1,p2...pk p1,p2...pk的异或和(如果无法确定输出I don't know.
)
处理以上操作时,如果有矛盾的,输出
The first i facts are conflicting.
( i i i为第一个矛盾的操作编号),然后忽略这组数据以下的赋值操作和询问操作。
数据
输入
多组数据。以0 0
结束。
每组数据:
n m
//数列长度,操作个数(n<=20000,m<=40000)
operation
//一个操作,格式如上
输出
Case #i:
ans
ans
...
ans
//(ans=一个整数,I dont't know或者The first i facts are conflicting.)
样例
输入
2 6
I 0 1 3
Q 1 0
Q 2 1 0
I 0 2
Q 1 1
Q 1 0
3 3
I 0 1 6
I 0 2 2
Q 2 1 2
2 4
I 0 1 7
Q 2 0 1
I 0 1 8
Q 2 0 1
0 0
输出
Case 1:
I don't know.
3
1
2
Case 2:
4
Case 3:
7
The first 2 facts are conflicting.
思路
(注:题目中是 0 0 0编号,我就被掰弯了,也是 0 0 0编号。)
( 1 1 1编号了那么久。。。)
这个题。。。没做过的话,真的不会想到用并查集做。。。
我们维护一个并查集,带权,其中权值用 X o r Xor Xor数组表示, X o r [ i ] Xor[i] Xor[i]是 i i i和 i i i父亲的异或值。
那么,我们不是要资瓷路径压缩的么。。。怎么压缩捏。。。
part1. 找祖先(Find函数),带路径压缩
设 f a [ i ] fa[i] fa[i]为 i i i的父亲, a a a是那个要确定的序列, ⊕ \oplus ⊕是异或
我们只要能把 X o r [ i ] Xor[i] Xor[i]用 O ( 1 ) O(1) O(1)的复杂度从原本的
a [ i ] ⊕ a [ f a [ i ] ] a[i] \oplus a[fa[i]] a[i]⊕a[fa[i]]
变成
a [ i ] ⊕ a [ f a [ f a [ i ] ] ] a[i] \oplus a[fa[fa[i]]] a[i]⊕a[fa[fa[i]]]。
我们会发现, X o r [ f a [ i ] ] = a [ f a [ i ] ] ⊕ a [ f a [ f a [ i ] ] ] Xor[fa[i]]=a[fa[i]]\oplus a[fa[fa[i]]] Xor[f