ARC061D 题解

先进行一个模型转换:要求满足以下条件的字符串数量:

  • abc 三种字符组成。
  • 其中恰好有 $n$ 个 a,且以 a 结尾。
  • b 不超过 $m$ 张,c 不超过 $k$ 张。

思考转换的过程:每个字符对应抽到的卡牌。其中第二条保证了 a 会胜利,第三条保证了这个过程中 bc 不会出现已经赢了的情况。

那么有:$$ \text{ans}=\sum_{t=0}^{m+k} (C_{t+n-1}^{n-1}\times(\sum_{x=t-k}^{m} C_{t}^{x})\times 3^{m+k-t}) $$ 设:$$ f(t)=\sum_{x=t-k}^{m} C_{t}^{x} $$ 则:$$ \begin{aligned} f(t)&=\sum_{x=t-k}^{m} (C_{t-1}^{x}+C_{t-1}^{x-1}) \\ &=(\sum_{x=t-k}^{m}C_{t-1}^{x})+(\sum_{x=t-k}^{m}C_{t-1}^{x-1}) \\ &=(\sum_{x=t-k}^{m}C_{t-1}^{x})+(\sum_{x=t-k-1}^{m-1}C_{t-1}^{x}) \\ &=(f(t-1)-C_{t-1}^{t-k-1})+(f(t-1)-C_{t-1}^{m}) \\ &=2 \times f(t-1)-C_{t-1}^{t-k-1}-C_{t-1}^{m} \end{aligned} $$ 发现现在可以在 $O(n \log {10^9+7})$ 的复杂度递推求出 $f(t)$。我们把 $f(t)$ 带入原式:$$ \text{ans}=\sum_{t=0}^{m+k} (C_{t+n-1}^{n-1}\times f(t)\times 3^{m+k-t}) $$

当然,用来算组合数的逆元以及 $3$ 的幂次可以线性预处理,这样时间复杂度降为线性。

#include <bits/stdc++.h>
#define L(i, a, b) for(int i = a; i <= b; i++)
#define R(i, a, b) for(int i = a; i >= b; i--)
using namespace std;
const int N = 3e5 + 10, mod = 1e9 + 7;
int n, m, k, fac[N * 3], f[N * 2], ans;
int qpow(int a, int b){
    int ans = 1;
    while(b){
        if(b & 1) ans = 1ll * ans * a % mod;
        a = 1ll * a * a % mod, b >>= 1;
    }
    return ans;
}
int inv(int x){return qpow(x, mod - 2);}
int C(int n, int m){
    if(m < 0 || m > n) return 0;
    return 1ll * fac[n] * inv(fac[m]) % mod * inv(fac[n - m]) % mod;
}
int main(){
    scanf("%d%d%d", &n, &m, &k); fac[0] = f[0] = 1;
    L(i, 1, n + m + k) fac[i] = 1ll * fac[i - 1] * i % mod;
    L(i, 1, m + k) f[i] = (2ll * f[i - 1] - C(i - 1, i - k - 1) - C(i - 1, m) + mod * 2) % mod;
    L(i, 0, m + k) (ans += 1ll * C(i + n - 1, n - 1) * f[i] % mod * qpow(3, m + k - i) % mod) %= mod;
    printf("%d\n", ans);
    return 0;
}
posted @ 2023-05-05 21:31  徐子洋  阅读(12)  评论(0)    收藏  举报  来源