1 条题解

  • 0
    @ 2025-8-13 11:59:32

    Subtask 0\texttt{Subtask 0}

    爆搜。或者直接输出 mm

    Subtask 0.5\texttt{Subtask 0.5}

    aia_i 为最终赢到 ii 澳元的方案数,cic_i 表示是否有面值为 ii 的筹码(有为 11,没有为 00),则 ana_n 为答案。

    递推式:

    a1=c1a_1=c_1 $$a_{i+1}=(a_{\lceil\frac{i+1}{2}\rceil}+\ldots+a_{i-1}+a_i)+c_{i+1} $$

    时间 / 空间复杂度为 O(n2+m)/O(n+m)O(n^2+m)/O(n+m)

    Subtask 1\texttt{Subtask 1}

    bib_iaia_i 的前缀和(b1=a1b_1=a_1bi=bi1+aib_i=b_{i-1}+a_i),注意到 $\lceil\dfrac{i+1}{2}\rceil=\lfloor\dfrac{i}{2}\rfloor+1$,则 bnbn1b_n-b_{n-1} 为答案。

    b1=c1b_1=c_1 $$b_{i+1}=(b_i+b_i-b_{\lfloor\frac{i}{2}\rfloor})+c_{i+1} $$

    时间 / 空间复杂度为 O(n+m)/O(n+m)O(n+m)/O(n+m)

    Subtask 2\texttt{Subtask 2}

    不难发现,求 bi+1b_{i+1} 时只需要 bib_ibi2b_{\lfloor\frac{i}{2}\rfloor} 的值。于是,我们可以每次只存 $b_i,b_{\lfloor\frac{i}{2}\rfloor},b_{\lfloor\frac{i}{4}\rfloor},b_{\lfloor\frac{i}{8}\rfloor},\ldots,b_1$ 的值。例如:

    ii 存储的下标
    11
    22 2,12,1
    33 3,13,1
    44 4,2,14,2,1
    55 5,2,15,2,1
    66 6,3,16,3,1
    77 7,3,17,3,1
    88 8,4,2,18,4,2,1
    \ldots

    不难发现,每次从右往前更新即可。时间 / 空间复杂度为 O(n+m)/O(m+logn)O(n+m)/O(m+ \log n)

    参考代码(std)

    #include <bits/stdc++.h>
    using namespace std;
    const int B = 32, P = 1e9 + 7, M = 1e6 + 5;
    int b[B], p[B], a[M];
    int main()
    {
        int n, m, s = 0;
        cin >> n >> m;
        for (int i = 1; i <= m; i++)
            cin >> a[i];
        for (int i = 1; i <= n; i++)
        {
            int t = i & (-i);
            for (int j = 1, k = 1, l = i; k <= t; j++, k <<= 1, l >>= 1)
            {
                b[j] <<= 1;
                b[j] -= b[j + 1];
                if (p[j] != m && a[p[j] + 1] == l) b[j]++, p[j]++;
                b[j] %= P;
                if (b[j] < 0) b[j] += P;
            }
            if (i == n - 1) s -= b[1];
            if (i == n) s += b[1];
        }
        cout << (s % P + P) % P;
        return 0;
    }
    

    信息

    ID
    255
    时间
    2000ms
    内存
    16MiB
    难度
    7
    标签
    递交数
    1
    已通过
    1
    上传者