E1. Prime Gaming (Easy Version)

E1. Prime Gaming (Easy Version)

This is the easy version of the problem. The difference between the versions is that in this version, $m \le 2$. You can hack only if you solved all versions of this problem.

A valid configuration is defined as an arrangement of $n$ piles of stones such that:

  • The number of stones in each pile is an integer between $1$ and $m$ (both inclusive).

Given a valid configuration of $n$ piles of stones, some indices from $1$ to $n$ are marked as good. Alice and Bob start playing a game taking $n-1$ turns alternately with Alice going first. In each turn, they have to perform the following operation:

  • Choose any integer $i$ such that $1 \le i \le p$ (where $p$ is the number of piles left) and $i$ is good, and remove the $i$-th pile completely.

Note that after performing the operation once, the number of piles decreases by $1$ and the remaining piles are re-indexed. The game will end when there is only one pile left. It is guaranteed that the index $1$ is always good.

Let $x$ denote the number of stones in the final remaining pile. Alice wants to maximize $x$, whereas Bob wants to minimize it. Both Alice and Bob play optimally.

Find the sum of $x$ over all the possible valid configurations modulo $10 ^ 9 + 7$.

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 testcase contains two integers $n$ ($1 \le n \le 20$) and $m$ ($1 \le m \le 2$) — the number of piles and the upper bound on the number of stones in a pile.

The second line of each testcase contains a single integer $k$ ($1 \le k \le n$) — the number of indices marked as good.

The third line of each testcase contains $k$ integers $c_1,c_2,\ldots,c_k$ ($1=c_1<c_2<\ldots<c_k\le n$) — the good indices. It is guaranteed that $1$ is always a good index (i.e. $c_1=1$).

It is guaranteed that the sum of $2^n$ over all test cases does not exceed $2^{20}$.

It is guaranteed that the sum of $m$ over all test cases does not exceed $10^6$.

Output

For each testcase, print a single integer — the sum of $x$ over all the possible valid configurations modulo $10 ^ 9 + 7$.

Example

Input

3
2 2
1
1
3 1
2
1 3
3 2
2
1 2

Output

6
1
11

Note

For the first test case, the valid configurations are: $[1, 1]$, $[1,2]$, $[2, 1]$, $[2, 2]$.

As there are only $2$ piles of stones, Alice can only choose the first pile and remove it. Thus, the sum of $x$ is equal to $1+1+2+2=6$.

For the second test case, the final pile is always $1$.

 

解题思路

  首先如果 $m=1$,则答案恒为 $1$。这是因为此时每堆石子的数量均为 $1$,不管怎么取最终剩下的那堆石子的数量也只能是 $1$。

  接下来我们考虑 $m=2$ 的情况。由于 $n \leq 20$ 很小,很容易想到先暴力枚举 $2^n$ 种初始状态,再根据每种初始状态求解最终剩下的石子的数量。由于我们已经用 $O(2^n)$ 的复杂度枚举了所有的初始状态,因此只能用 $O(n)$ 的方法来对每个初始状态进行求解。这意味着我们只能采用贪心策略或寻找某种规律,但这种方式并不容易直接想到(也不一定有)。此外,我们知道,如果将每个局面看作节点,局面之间的转移看作边,我们就能得到一个有向无环图。通过从最终状态(即只剩一堆石子的局面)反向推导出每个状态对应的最终结果,进而得到初始状态的结果。但遍历整个图的复杂度是 $O(2^n)$,总的复杂度就是 $O(4^n)$,不可行。

  但是再细想一下就会发现,虽然初始状态有 $2^n$ 种,但游戏过程中会有大量的中间状态重复。比如初始状态 $[1,2,1,1]$ 与 $[1,1,2,1,1]$ 在取走石子后,都会经过状态 $[1,1,1]$、$[1,2,1]$ 和 $[2,1,1]$。因此,如果对每个初始状态都单独求解,许多中间状态将被重复计算。事实上,根据局面剩余石子堆数进行分类,实际上所有可能的状态只有 $\sum\limits_{i=1}^{n}{2^i} = \sum\limits_{i=0}^{n}{2^i} - 1 = 2^{n+1}-2$ 种。因此我们可以在计算出每个节点的结果后进行记忆化,从而避免重复遍历这些节点。

  定义状态 $f(i,j,k)$,其中为当前石子堆数 $i$,$j$ 为当前局面状态($j$ 的二进制前位 $i$ 中,$1$ 表示该堆石子数量为 $2$,$0$ 表示该堆石子数量为 $1$),$k$ 为当前玩家($1$ 表示 Alice,$0$ 表示 Bob)。状态 $f(i,j,k)$ 表示在局面 $j$ 下,玩家 $k$ 先手能获得的最大结果。根据选择取走石子堆的位置进行状态转移,状态转移方程为 $$\begin{cases} f(i,j,k) = \max_{c_u \leq i}\{f(i-1,g(j,c_u),k \oplus 1) \}, &k=1 \\ f(i,j,k) = \min_{c_u \leq i}\{f(i-1,g(j,c_u),k \oplus 1) \}, &k=0 \\ \end{cases}$$

  其中 $g(j,c_u)$ 表示从状态 $j$ 取走第 $c_u$ 堆石子后的状态,对应 $j$ 的二进制中,移除第 $c_u$ 位并将第 $c_u + 1$ 位及之后的位依次向低位移动。对应的代码实现为 (j & (1 << c[u] - 1) - 1) | (j >> c[u] << c[u] - 1)

  最后答案就是 $\sum\limits_{i=0}^{2^n - 1}{f(n,i,1)}$。

  AC 代码如下,时间复杂度为 $O(n 2^n)$:

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

typedef long long LL;

const int N = 25, M = 1 << 20;

int n, m, l;
int c[N];
int f[N][M][2];

int get(int x, int k) {
    return (x & (1 << k - 1) - 1) | (x >> k << k - 1);
}

int dfs(int i, int j, int k) {
    if (i == 1) return f[i][j][k] = (j & 1) + 1;
    if (abs(f[i][j][k]) <= 2) return f[i][j][k];
    for (int u = 0; u < l; u++) {
        if (c[u] > i) break;
        int t = dfs(i - 1, get(j, c[u]), k ^ 1);
        if (k) f[i][j][k] = max(f[i][j][k], t);
        else f[i][j][k] = min(f[i][j][k], t);
    }
    return f[i][j][k];
}

void solve() {
    cin >> n >> m >> l;
    for (int i = 0; i < l; i++) {
        cin >> c[i];
    }
    if (m == 1) {
        cout << 1 << '\n';
    }
    else {
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < 1 << i; j++) {
                f[i][j][0] = 0x3f3f3f3f;
                f[i][j][1] = -0x3f3f3f3f;
            }
        }
        int ret = 0;
        for (int i = 0; i < 1 << n; i++) {
            ret += dfs(n, i, 1);
        }
        cout << ret << '\n';
    }
}

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

 

参考资料

  Codeforces Round 1049 (Div. 2) Editorial:https://codeforces.com/blog/entry/146218

posted @ 2025-09-17 18:51  onlyblues  阅读(35)  评论(0)    收藏  举报
Web Analytics