Loading

[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

首先异或有两个运算定律:

  1. 自反律: \(x \operatorname{xor} y \operatorname{xor} y = x\)

  2. 结合律: \(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;
}
posted @ 2022-11-10 10:02  reechee  阅读(16)  评论(0)    收藏  举报