- P194's solution
P194's Solution
- 2025-9-4 22:00:10 @
爆搜。或者直接输出 。
设 为最终赢到 澳元的方案数, 表示是否有面值为 的筹码(有为 ,没有为 ),则 为答案。
递推式:
$$a_{i+1}=(a_{\lceil\frac{i+1}{2}\rceil}+\ldots+a_{i-1}+a_i)+c_{i+1} $$时间 / 空间复杂度为 。
设 为 的前缀和(,),注意到 $\lceil\dfrac{i+1}{2}\rceil=\lfloor\dfrac{i}{2}\rfloor+1$,则 为答案。
$$b_{i+1}=(b_i+b_i-b_{\lfloor\frac{i}{2}\rfloor})+c_{i+1} $$时间 / 空间复杂度为 。
不难发现,求 时只需要 及 的值。于是,我们可以每次只存 $b_i,b_{\lfloor\frac{i}{2}\rfloor},b_{\lfloor\frac{i}{4}\rfloor},b_{\lfloor\frac{i}{8}\rfloor},\ldots,b_1$ 的值。例如:
存储的下标 | |
---|---|
不难发现,每次从右往前更新即可。时间 / 空间复杂度为 。
参考代码(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;
}