首页 > 其他 > 详细

【BZOJ4555】【TJOI2016】【HEOI2016】求和

时间:2018-08-05 12:34:25      阅读:152      评论:0      收藏:0      [点我收藏+]

题目

传送门

解法

我们可以用容斥来求第二类斯特林数

我们知道, 第二类斯特林数\(S(n, k)\)\(n\)个元素放进\(k\)个无标号的盒子里, 不可以含有空的。 于是我们可以考虑可以含有空的,且盒子有标号, 情况下的数量, 这明显是\(\sum\limits_{j = 0}^{k}{k \choose j}(k-j)^n\)

于是, 根据容斥原理可得:\(S(n, k) = \frac{1}{k!}\sum_{j = 0}^{k}(k-j)^n{k \choose j}(-1)^i\)

于是

\[ \begin{align} &\sum_{i = 0}^{n}\sum_{j = 0}^{i}S(i, j)\&=\sum_{i = 0}^{n}\sum_{j = 0}^{n}S(i, j)\&=\sum_{i = 0}^{n}\sum_{j = 0}^{n}2^jj!{\frac{1}{j!}}\sum_{k = 0}^{j}(j-k)^i(-1)^j{j \choose k}\&= \sum_{i = 0}^{n}\sum_{j = 0}^{n}2^j\sum_{k = 0}^{j}(j-k)^i(-1)^j\frac{j!}{k!(j-k)!}\&= \sum_{i = 0}^{n}\sum_{j = 0}^{n}2^j\sum_{k = 0}^{j}(j-k)^i(-1)^j\frac{j!}{k!(j-k)!}\&= \sum_{i = 0}^{n}\sum_{j = 0}^{n}2^jj!\sum_{k = 0}^{j}(j-k)^i(-1)^j\frac{1}{k!(j-k)!}\&= \sum_{i = 0}^{n}\sum_{j = 0}^{n}2^jj!\sum_{k = 0}^{j}(-1)^j\frac{(j-k)^i}{k!(j-k)!}\&= \sum_{i = 0}^{n}\sum_{j = 0}^{n}2^jj!\sum_{k = 0}^{j}(-1)^j\frac{1}{k!}\frac{(j-k)^i}{(j-k)!} \&= \sum_{j = 0}^{n}2^jj!\sum_{k = 0}^{j}(-1)^j\frac{1}{k!}\sum_{i = 0}^{n}\frac{(j-k)^i}{(j-k)!} \end{align} \]

于是, 这里出现了一个感人肺腑的卷积

我们设\(a(x) = \frac{1}{x!}(-1)^x\), \(b(x) = \sum_{k = 0}^{n}{k^{i}\over k!}\)

于是答案是\(\sum\limits_{j = 0}^{n}\sum\limits_{k = 0}^{j}a(k)b(j-k)\)

\(b\)可以用等比数列求和公式求出

代码

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstdlib>
#include <algorithm>

using namespace std;

typedef long long LL;

const LL mod = 998244353LL;

const int N = 400010;

inline LL power(LL a, LL n, LL mod)
{   LL Ans = 1;
    a %= mod;
    while (n)
    {   if (n & 1) Ans = (Ans * a) % mod;
        a = (a * a) % mod;
        n >>= 1;
    }
    return Ans;
}

inline LL Plus(LL a, LL b) { return a + b > mod ? a + b - mod : a + b; }

inline LL Minus(LL a, LL b) { return a - b < 0 ? a - b + mod : a - b; }

struct Mul
{   int Len, Bit;

    LL wn[N];

    int rev[N];

    void getReverse()
    {   for (int i = 0; i < Len; i++)
            rev[i] = (rev[i>>1] >> 1) | ((i&1) * (Len >> 1));
    }

    void NTT(LL * a, int opt)
    {   getReverse();
        for (int i = 0; i < Len; i++)
            if (i < rev[i]) swap(a[i], a[rev[i]]);
        int cnt = 0;
        for (int i = 2; i <= Len; i <<= 1)
        {   cnt++;
            for (int j = 0; j < Len; j += i)
            {   LL w = 1LL;
                for (int k = 0; k < (i>>1); k++)
                {   LL x = a[j + k];
                    LL y = (w * a[j + k + (i>>1)]) % mod;
                    a[j + k] = Plus(x, y);
                    a[j + k + (i>>1)] = Minus(x, y);
                    w = (w * wn[cnt]) % mod;
                }
            }
        }
        if (opt == -1)
        {   reverse(a + 1, a + Len);
            LL num = power(Len, mod-2, mod);
            for (int i = 0; i < Len; i++)
                a[i] = (a[i] * num) % mod;
        }
    }

    void getLen(int l)
    {   Len = 1, Bit = 0;
        for (; Len <= l; Len <<= 1) Bit++;
    }

    void init()
    {   for (int i = 0; i < 23; i++)
            wn[i] = power(3, (mod-1) / (1LL << i), mod);
    }
} Calc;

LL fac[N], ifac[N];

LL A[N], B[N], C[N];

int main()
{   int n;
    scanf("%d", &n);
    fac[0] = 1;
    for (int i = 1; i <= n; i++)
        fac[i] = fac[i-1] * i % mod;
    ifac[n] = power(fac[n], mod-2, mod);
    for (int i = n-1; i >= 0; i--)
        ifac[i] = ifac[i+1] * (i+1) % mod;
    for (int i = 0; i <= n; i++)
        A[i] = (i & 1 ? Minus(mod, 1) : 1) * ifac[i] % mod;
    B[0] = 1;
    B[1] = n + 1;
    for (int i = 2; i <= n; i++)
        B[i] = (power(i, n+1, mod) + mod - 1) % mod * power(i-1, mod-2, mod) % mod * ifac[i] % mod;
    Calc.init();
    Calc.getLen(n * 2 + 1);
    Calc.NTT(A, 1);
    Calc.NTT(B, 1);
    for (int i = 0; i < Calc.Len; i++)
        C[i] = A[i] * B[i] % mod;
    Calc.NTT(C, -1);
    LL Ans = 0;
    for (int i = 0; i <= n; i++)
        Ans = Plus(Ans, (power(2LL, i, mod) * fac[i] % mod * C[i] % mod));
    printf("%lld\n", Ans);
    return 0;
}

【BZOJ4555】【TJOI2016】【HEOI2016】求和

原文:https://www.cnblogs.com/2016gdgzoi509/p/9424872.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!