6300. Count

Description

详见OJ

Solution

首先看题,我们发现\(\sum{a[i]}=n\),所以可以理解为一个抽屉问题。
但它不仅有一条限制,而且\(n\)也十分的大。怎么办呢?
%%%sls大佬%%%想到可以将\(\sum{a[i]}\)拆分成\(\sum{b[i]*m+p[i]}(p[i]<m)\)
而对于\(b[i]\)可以用组合数直接求,那么对于\(p[i]\)呢?
我们不妨看看几个式子:
\(\sum{p[i]}≡n(mod m)\)
\(\sum{p[i]} <= k*(m - 1)\)
所以我们可以枚举\(\sum{p[i]}\)
但是,如果直接用组合数的话有些\(p[i]\)可能会超过\(m - 1\),这样我们就需要用到容斥了。
我们再枚举有多少个数(设为\(j\))超过了\(m-1\),然后先将\(\sum{p[i]}\)减去\(j*(m-1)\)
求出组合数后再将它任意放回去即可。最后不要忘了\(b[i]\)的组合数。

Code

#include <cstdio>
#define N 5010
#define maxn 10000000 
#define ll long long
#define mo 998244353
#define mem(x, a) memset(x, a, sizeof x)
#define fo(x, a, b) for (int x = a; x <= b; x++)
#define fd(x, a, b) for (int x = a; x >= b; x--)
using namespace std;
int m, K, nmm;
ll n, ans = 0, s;
ll jc[maxn + 10], ny[maxn + 10];

ll ksm(ll x, int y)
{
    ll s = 1;
    while (y)
    {
        if (y & 1) s = s * x % mo;
        x = x * x % mo; y >>= 1;
    }
    return s;
}

ll C(int x, int y) {return x > y ? 0 : jc[y] * ny[x] % mo * ny[y - x] % mo;}

ll calc(ll x, ll y)
{
    if (x > y) return 0;
    ll s = 1;
    for (ll i = y - x + 1; i <= y; i++) s = s * (i % mo) % mo;
    s = s * ny[x] % mo;
    return s;
}

int main()
{
    freopen("count.in", "r", stdin);
    freopen("count.out", "w", stdout);
    scanf("%lld%d%d", &n, &m, &K); nmm = n % m;
    if (m == 1) {puts("0"); return 0;}
    if (K == 1) {printf("%d\n", n % m == 0 ? 0 : 1); return 0;}
    jc[0] = ny[0] = 1;
    fo(i, 1, maxn) jc[i] = jc[i - 1] * i % mo;
    ny[maxn] = ksm(jc[maxn], mo - 2);
    fd(i, maxn - 1, 1) ny[i] = ny[i + 1] * (i + 1) % mo;
    for (ll sump = nmm; sump <= K * (m - 1); sump += m)
    {
        s = 0;
        fo(i, 0, K)
        {
//          printf("%lld %lld\n", K - 1, sump - i * (m - 1) - 1);
            s = (s + C(K - 1, sump - i * (m - 1) - 1) * C(i, K) % mo * ((i & 1) ? -1 : 1)) % mo;
        }
//      printf("%lld %lld\n", sump, s);
        ans = (ans + s * calc(K - 1, K + (n - sump) / m - 1) % mo) % mo;
//      printf("%lld\n", ans);
    }
    printf("%lld\n", (ans + mo) % mo);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/jz929/p/11348629.html
今日推荐