[ABC171E] Red Scarf 题解
Problem
给出一个长为 \(N\) 的序列 \(a\),\(a_i\) 为原始序列 \(b\) 上的每一个除了 \(b_i\) 其它所有数的异或和,求出原始序列 \(b\)。
\(2 \leq N \leq 200000\),\(0 \leq a_i \leq 10^9\),且 \(N\) 为偶数。
Algorithm #1 100pts
首先异或有两个运算定律:
-
自反律: \(x \operatorname{xor} y \operatorname{xor} y = x\)。
-
结合律: \(x \operatorname{xor} y \operatorname{xor} z = x \operatorname{xor} (y \operatorname{xor} z) = (x \operatorname{xor} y) \operatorname{xor} z\)。
考虑将 \(a_i\) 展开成 \(b_i\) 的形式:
\(a_1=b_2 \operatorname{xor} b_3 \operatorname{xor} \dots \operatorname{xor} b_n\)
\(a_2=b_1 \operatorname{xor} b_3 \operatorname{xor} \dots \operatorname{xor} b_n\)
\(a_3=b_1 \operatorname{xor} b_2 \operatorname{xor} \dots \operatorname{xor} b_n\)
因为自反律,其实也可以写成:
\(a_1=b_1 \operatorname{xor} b_2 \operatorname{xor} \dots \operatorname{xor} b_n \operatorname{xor} b_1\)
\(a_2=b_1 \operatorname{xor} b_2 \operatorname{xor} \dots \operatorname{xor} b_n \operatorname{xor} b_2\)
\(a_3=b_1 \operatorname{xor} b_2 \operatorname{xor} \dots \operatorname{xor} b_n \operatorname{xor} b_3\)
\(\dots\)
\(a_i=b_1 \operatorname{xor} b_2 \operatorname{xor} \dots \operatorname{xor} b_n \operatorname{xor} b_i\)
结合一下:
\(a_i=(b_1 \operatorname{xor} b_2 \operatorname{xor} \dots \operatorname{xor} b_n) \operatorname{xor} b_i\)
统计 \(a_i\) 的异或和 \(k\),因为 \(N\) 为偶数,所以前面整体消去。
最终可以发现 \(a_i\) 的异或和即为 \(b_i\) 的异或和。
而又因 \(a_i=b_1 \operatorname{xor} b_2 \operatorname{xor} \dots \operatorname{xor} b_n \operatorname{xor} b_i\),所以 \(k \operatorname{xor} a_i=(b_1 \operatorname{xor} b_2 \operatorname{xor} \dots \operatorname{xor} b_n) \operatorname{xor} (b_1 \operatorname{xor} b_2 \operatorname{xor} \dots \operatorname{xor} b_n \operatorname{xor} b_i)=b_i\)。
输入时统计 \(a_i\) 的异或和,最后对于每一个 \(a_i\) 输出 \(k \operatorname{xor} a_i\) 即可。
时间复杂度 \(\mathcal{O}(n)\)。
Code
ll n,a[N],k;
int main(){
n=read();
F(i,1,n){
a[i]=read();
k^=a[i];
}
F(i,1,n)
printf("%lld ",k^a[i]);
return 0;
}