Bitwise XOR

题目描述

Given a sequence $a$ and an empty sequence $b$, each element in $a$ is added to $b$ with probability $P$ (independently to the other elements). Denote $s=\bigoplus_{i=1}^{|b|} b_i$, where $\oplus$ denotes bitwise xor and $s=0$ if $b$ is empty. Find the expected value of $s^2$.

题意概述

给定一个长度为$n$的序列$a$,其中每个数都有$P$的概率被选中。令被选中的数的异或和为$s$。求$s^2$的期望。

数据范围:$1 \le n \le 10^5, \ 0 \le a_i \lt 10^9+7$

算法分析

令$P(s)$表示异或和为$s$的概率。把$s$用二进制表示,最低位为第$0$位。

$$
\begin{align} \sum_s s^2P(s) &= \sum_s (\sum_{i=0}^{29} [s二进制第i位为1] 2^i)^2P(s) \\ &= \sum_s P(s) \sum_{i=0}^{29} [s二进制第i位为1] 2^i \sum_{j=0}^{29} [s二进制第j位为1] 2^j \\ &= \sum_s P(s) \sum_{i=0}^{29} \sum_{j=0}^{29} [s二进制第i位和第j位都为1] 2^{i+j} \\ &= \sum_{i=0}^{29} \sum_{j=0}^{29} P(s二进制第i位和第j位都为1) 2^{i+j} \end{align}
$$

先枚举$i$和$j$,令$f_{k,0/1,0/1}$表示从前$k$个数中选,异或和第$i$位、第$j$为分别为$0/1$、$0/1$的概率,对$f_{n,1,1}2^{i+j}$求和即为答案。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <cstdio>
#include <cstring>
#include <algorithm>

int const N = 100005, MOD = 1000000007;

int a[N], f[N][2][2];

int power(int a, int b) {
int ret = 1;
for (; b; b >>= 1) {
if (b & 1) {
ret = 1ll * ret * a % MOD;
}
a = 1ll * a * a % MOD;
}
return ret;
}

int main() {
int n, x, y;
scanf("%d%d%d", &n, &x, &y);
int p = 1ll * x * power(y, MOD - 2) % MOD, q = (MOD + 1 - p) % MOD;
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
int ans = 0, ans2 = 0;
f[0][0][0] = 1;
for (int i = 0; i < 30; ++i) {
for (int j = i; j < 30; ++j) {
for (int k = 1; k <= n; ++k) {
for (int _i = 0; _i < 2; ++_i) {
for (int _j = 0; _j < 2; ++_j) {
int __i = _i ^ (a[k] >> i & 1);
int __j = _j ^ (a[k] >> j & 1);
f[k][_i][_j] = (1ll * f[k - 1][_i][_j] * q + 1ll * f[k - 1][__i][__j] * p) % MOD;
}
}
}
ans = (ans + (1ll << i + j + (i != j)) % MOD * f[n][1][1]) % MOD;
}
}
printf("%d\n", ans);
return 0;
}

Bitwise XOR
https://regmsif.cf/2020/02/04/oi/bitwise-xor/
作者
RegMs If
发布于
2020年2月4日
许可协议