• Yet Another RGB Sequence(排列组合)


    题意

    问有多少字符串满足如下要求:

    • 只包含RGB三种字符,并且数量分别是\(A\)\(B\)\(C\)
    • 包含\(K\)个连续子串RG

    题目链接:https://atcoder.jp/contests/abc266/tasks/abc266_g

    数据范围

    \(1 \leq A,B,C \leq 10^6\)

    思路

    我们将题目转化一下,有\(A+B+C\)个位置上要放RGB三种字符。其中RG\(K\)个,R\(A-K\)个,G\(B-K\)个,B\(C\)个。

    我们可以将RG当做是一个字符,因此唯一的限制就在于除了RG之外的其他RG

    因此,我们可以将RGRB随便放,方案数是\(\frac{(K + (A - K) + C)!}{K!(A-K)!C!}\)

    然后考虑放G。本来有\(K + (A - K) + C + 1\)个位置,但是由于不能放在R的后面,因此实际可以放的位置为\(K + C + 1\)个。

    这样就转化成了一个不定方程解的个数问题,方案数为\(\binom{(B-K) + (K + C + 1) - 1}{(K +C+1)-1} = \binom{B+C}{C+K}\)

    因此最终结果为\(\frac{(A + C)!}{K!(A-K)!C!} \cdot \binom{B+C}{C+K}\)

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long ll;
    
    const int N = 2000010, mod = 998244353;
    
    ll a, b, c, k;
    ll fac[N], infac[N];
    
    ll qmi(ll a, ll b)
    {
        ll res = 1;
        while(b) {
            if(b & 1) res = res * a % mod;
            b >>= 1;
            a = a * a % mod;
        }
        return res;
    }
    
    void init()
    {
        fac[0] = infac[0] = 1;
        for(int i = 1; i < N; i ++) {
            fac[i] = fac[i - 1] * i % mod;
            infac[i] = infac[i - 1] * qmi(i, mod - 2) % mod;
        }
    }
    
    int main()
    {
        cin >> a >> b >> c >> k;
        init();
        ll res = fac[a + c] * infac[a - k] % mod * infac[c] % mod * infac[k] % mod;
        res = res * fac[b + c] % mod * infac[c + k] % mod * infac[b - k] % mod;
        cout << res << endl;
        return 0;
    }
    
  • 相关阅读:
    DBG
    gdb Debugging Full Example
    Java Warmup
    Dtrace for Linux 2016
    分布式系统理论进阶
    Java theory and practice
    Dealing with InterruptedException
    JVM 虚拟化
    Intro to Filtering with Network Monitor 3.0
    spring 官方文档
  • 原文地址:https://www.cnblogs.com/miraclepbc/p/16651314.html
Copyright © 2020-2023  润新知