E. Expected Power

onlyblues發表於2024-10-07

E. Expected Power

You are given an array of $n$ integers $a_1,a_2,\ldots,a_n$. You are also given an array $p_1, p_2, \ldots, p_n$.

Let $S$ denote the random multiset (i. e., it may contain equal elements) constructed as follows:

  • Initially, $S$ is empty.
  • For each $i$ from $1$ to $n$, insert $a_i$ into $S$ with probability $\frac{p_i}{10^4}$. Note that each element is inserted independently.

Denote $f(S)$ as the bitwise XOR of all elements of $S$. Please calculate the expected value of $(f(S))^2$. Output the answer modulo $10^9 + 7$.

Formally, let $M = 10^9 + 7$. It can be shown that the answer can be expressed as an irreducible fraction $\frac{p}{q}$, where $p$ and $q$ are integers and $q \not \equiv 0 \pmod{M}$. Output the integer equal to $p \cdot q^{-1} \bmod M$. In other words, output such an integer $x$ that $0 \le x < M$ and $x \cdot q \equiv p \pmod{M}$.

Input

Each test contains multiple test cases. The first line contains the number of test cases $t$ ($1 \le t \le 10^4$). The description of the test cases follows.

The first line of each test case contains a single integer $n$ ($1 \le n \le 2 \cdot 10^5$).

The second line of each test case contains $n$ integers $a_1,a_2,\ldots,a_n$ ($1 \le a_i \le 1023$).

The third line of each test case contains $n$ integers $p_1,p_2,\ldots,p_n$ ($1 \le p_i \le 10^4$).

It is guaranteed that the sum of $n$ over all test cases does not exceed $2 \cdot 10^5$.

Output

For each test case, output the expected value of $(f(S))^2$, modulo $10^9 + 7$.

Example

Input

4
2
1 2
5000 5000
2
1 1
1000 2000
6
343 624 675 451 902 820
6536 5326 7648 2165 9430 5428
1
1
10000

Output

500000007
820000006
280120536
1

Note

In the first test case, $a = [1, 2]$ and each element is inserted into $S$ with probability $\frac{1}{2}$, since $p_1 = p_2 = 5000$ and $\frac{p_i}{10^4} = \frac{1}{2}$. Thus, there are $4$ outcomes for $S$, each happening with the same probability of $\frac{1}{4}$:

  • $S = \varnothing$. In this case, $f(S) = 0$, $(f(S))^2 = 0$.
  • $S = \{1\}$. In this case, $f(S) = 1$, $(f(S))^2 = 1$.
  • $S = \{2\}$. In this case, $f(S) = 2$, $(f(S))^2 = 4$.
  • $S = \{1,2\}$. In this case, $f(S) = 1 \oplus 2 = 3$, $(f(S))^2 = 9$.

Hence, the answer is $0 \cdot \frac{1}{4} + 1 \cdot \frac{1}{4} + 4\cdot \frac{1}{4} + 9 \cdot \frac{1}{4} = \frac{14}{4} = \frac{7}{2} \equiv 500\,000\,007 \pmod{10^9 + 7}$.

In the second test case, $a = [1, 1]$, $a_1$ is inserted into $S$ with probability $0.1$, while $a_2$ is inserted into $S$ with probability $0.2$. There are $3$ outcomes for $S$:

  • $S = \varnothing$. In this case, $f(S) = 0$, $(f(S))^2 = 0$. This happens with probability $(1-0.1) \cdot (1-0.2) = 0.72$.
  • $S = \{1\}$. In this case, $f(S) = 1$, $(f(S))^2 = 1$. This happens with probability $(1-0.1) \cdot 0.2 + 0.1 \cdot (1-0.2) = 0.26$.
  • $S = \{1, 1\}$. In this case, $f(S) = 0$, $(f(S))^2 = 0$. This happens with probability $0.1 \cdot 0.2 = 0.02$.

Hence, the answer is $0 \cdot 0.72 + 1 \cdot 0.26 + 0 \cdot 0.02 = 0.26 = \frac{26}{100} \equiv 820\,000\,006 \pmod{10^9 + 7}$.

解題思路

  由於 $1 \leq a_i \leq 1023$,因此有 $S \in [0, 1023]$(這裡的 $S$ 表示集合內元素的異或值)。一種求期望的做法是分別求出每個 $S$ 對應的 $S^2$ 的期望再求和,也就是 $\sum\limits_{S=0}^{1023}{P_S \cdot S^2}$,其中 $P_S$ 表示異或結果等於 $S$ 的機率。

  $P_S$ 可以透過簡單的 dp 求得。定義 $f(i,j)$ 表示從前 $i$ 個數中選出異或結果為 $j$ 的集合的機率,根據是否選擇第 $i$ 個數進行狀態轉移,有狀態轉移方程 $f(i,j) = f(i-1, j) \cdot \left(1 - \frac{p_i}{10^4} \right) + f(i-1, j \oplus a_i) \cdot \frac{p_i}{10^4}$。

  最後要求的期望就是 $\sum\limits_{S=0}^{1023}{f(n, S) \cdot S^2}$。

  AC 程式碼如下,時間複雜度為 $O\left(n \cdot 2^{\left\lfloor\log{A}\right\rfloor + 1} \right)$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 2e5 + 5, M = 1 << 10, mod = 1e9 + 7;

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

void solve() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 1; i <= n; i++) {
        cin >> p[i];
    }
    memset(f[0], 0, sizeof(f[0]));
    f[0][0] = 1;
    for (int i = 1; i <= n; i++) {
        memset(f[i & 1], 0, sizeof(f[0]));
        for (int j = 0; j < M; j++) {
            f[i & 1][j] = ((10000 - p[i]) * 285700002ll % mod * f[i - 1 & 1][j] + p[i] * 285700002ll % mod * f[i - 1 & 1][j ^ a[i]]) % mod;
        }
    }
    int ret = 0;
    for (int i = 0; i < M; i++) {
        ret = (ret + 1ll * f[n & 1][i] * i % mod * i) % mod;
    }
    cout << ret << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    
    return 0;
}

  實際上是因為 $a_i$ 的值域太小所以才放過上面的暴力做法,下面給出正解。

  如果單純求的是 $S$ 的期望,我們容易想到拆位然後分別考慮每一位對期望的貢獻。$S^2$ 也是可以這樣做的,有$$\begin{align*} S^2 &= \left( b_9 \cdot 2^9 + b_8 \cdot 2^8 + \cdots +b_0 \cdot 2^0 \right)^2 \\ &= \sum\limits_{i=0}^{9}{\sum\limits_{j=0}^{9}}{b_i b_j \cdot 2^{i+j}} \end{align*}$$

  所以現在我們需要求出每個 $b_i b_j = 1$ 的機率是多少,記為 $P_{i,j}$,那麼所求期望就是 $\sum\limits_{i=0}^{9}{\sum\limits_{j=0}^{9}}{P_{i,j} \cdot 2^{i+j}}$。而 $P_{i,j}$ 同樣可以用 dp 求得。

  定義 $f(i,j,k,u,v)$ $(u,v \in \{0,1\})$ 表示從前 $i$ 個數中選出異或結果的二進位制的第 $j$ 位為 $u$ 且第 $k$ 位為 $v$ 的集合的機率,一樣根據是否選擇第 $i$ 個數進行狀態轉移,狀態轉移方程就是 $f(i,j,k,u,v) = f(i-1,j,k,u,v) \cdot \left(1 - \frac{p_i}{10^4} \right) + f(i-1,j,k,u \oplus a_{i,u} ,v \oplus a_{i,v}) \cdot \frac{p_i}{10^4}$,其中 $a_{i,j}$ 表示 $a_i$ 的二進位制第 $j$ 位的值。

  最後要求的期望就是 $\sum\limits_{i=0}^{9}{\sum\limits_{j=0}^{9}}{f(n,i,j,1,1) \cdot 2^{i+j}}$。

  AC 程式碼如下,時間複雜度為 $O(n \log^2{A})$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 2e5 + 5, M = 10, mod = 1e9 + 7;

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

void solve() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 1; i <= n; i++) {
        cin >> p[i];
    }
    memset(f[0], 0, sizeof(f[0]));
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < M; j++) {
            f[0][i][j][0][0] = 1;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < M; j++) {
            for (int k = 0; k < M; k++) {
                for (int u = 0; u <= 1; u++) {
                    for (int v = 0; v <= 1; v++) {
                        f[i & 1][j][k][u][v] = ((10000 - p[i]) * 285700002ll % mod * f[i - 1 & 1][j][k][u][v] + p[i] * 285700002ll % mod * f[i - 1 & 1][j][k][u ^ (a[i] >> j & 1)][v ^ (a[i] >> k & 1)]) % mod;
                    }
                }
            }
        }
    }
    int ret = 0;
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < M; j++) {
            ret = (ret + (1ll << i + j) * f[n & 1][i][j][1][1]) % mod;
        }
    }
    cout << ret << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    
    return 0;
}

參考資料

  Tutorial for Codeforces Round 976 (Div. 2) and Divide By Zero 9.0:https://codeforces.com/blog/entry/134516

相關文章