[HEOI2016/TJOI2016]求和 斯特林数 + NTT

Description

计算函数的值

\[f(n) = \sum \limits_{i=0}^{n} \sum \limits_{j=0}^{i} 2^j \times j! \times S(i,j)\]

Solution

大家好,我是练习推柿子半天的个人练习生\(newbielyx\)。

\[
f(n) = \sum \limits_{i=0}^{n} \sum \limits_{j=0}^{i} 2^j \times j! \times S(i,j)
\]

\[
= \sum \limits_{i=0}^{n} \sum \limits_{j=0}^{i} 2^j \times j! \times \frac{1}{j!} \times \left (\sum \limits_{k=0}^{j} (-1)^k C(j,k)(j-k)^i\right)
\]

\[
= \sum \limits_{i=0}^{n} \sum \limits_{j=0}^{i} 2^j \sum \limits_{k=0}^{j} (-1)^k C(j,k)(j-k)^i
\]

\[
= \sum \limits_{j=0}^{n}2^j \sum \limits_{i=j}^{n} \sum \limits_{k=0}^{j} (-1)^k C(j,k) (j-k)^i
\]

\[
= \sum \limits_{j=0}^{n} 2^j \sum \limits_{k=0}^{j} (-1)^k C(j,k) \sum \limits_{i=0}^{n}(j-k)^i
\]

\[
= \sum \limits_{j=0}^{n} 2^j \sum \limits_{k=0}^{j} (-1)^k \frac{j!}{k!(j-k)!} \sum \limits_{i=0}^{n}(j-k)^i
\]

\[
= \sum \limits_{j=0}^{n} 2^j \cdot j! \sum \limits_{k=0}^{j} \frac{(-1)^k}{k!} \frac{\sum \limits_{i=0}^{n}(j-k)^i}{(j-k)!}
\]

容易看出上面是一个等比数列,继续推倒

\[
f(n) = \sum \limits_{j=0}^{n} 2^j \cdot j! \sum \limits_{k=0}^{j} \frac{(-1)^k}{k!} \frac{(j-k)^{n+1}-1}{(j-k-1)(j-k)!}
\]

\[
= \sum \limits_{j=0}^{n} 2^j \cdot j! \sum \limits_{k=0}^{j} \frac{(-1)^k}{k!} \frac{(j-k)^{n+1}-1}{(j-k)!(j-k-1)}
\]

然后你就可以发现,卷起来了!

Code

#include <bits/stdc++.h>
using namespace std;

inline int ty() {
    char ch = getchar(); int x = 0, f = 1;
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

typedef long long ll;
const ll P = 998244353, G = 3, Gx = 332748118;
const int _ = 4e5 + 10;
int N, r[_];
ll fac[_], facinv[_], A[_], B[_];

ll fpow(ll a, ll b) {
    ll ret = 1;
    for ( ; b; b >>= 1) {
        if (b & 1) ret = ret * a % P;
        a = a * a % P;
    }
    return ret;
}

inline void pre() {
    fac[0] = fac[1] = 1;
    for (int i = 2; i <= N; ++i) fac[i] = fac[i - 1] * i % P;
    facinv[0] = 1, facinv[N] = fpow(fac[N], P - 2);
    for (int i = N - 1; i >= 1; --i) facinv[i] = facinv[i + 1] * (i + 1) % P;
    for (int i = 0; i <= N; ++i) {
        A[i] = (i & 1) ? -1 : 1;
        A[i] = (A[i] * facinv[i] + P) % P;
    }
    for (int i = 2; i <= N; ++i) {
        B[i] = (fpow(i, N + 1) - 1 + P) % P;
        B[i] = B[i] * facinv[i] % P;
        B[i] = B[i] * fpow(i - 1, P - 2) % P;
    }
    B[0] = 1, B[1] = N + 1;
}

void NTT(int lim, ll *a, int op) {
    for (int i = 0; i < lim; ++i)
        if (i < r[i]) swap(a[i], a[r[i]]);
    for (int len = 2; len <= lim; len <<= 1) {
        int mid = len >> 1;
        ll Wn = fpow(op == 1 ? G : Gx, (P - 1) / len);
        for (int i = 0; i < lim; i += len) {
            ll w = 1;
            for (int j = 0; j < mid; ++j, w = w * Wn % P) {
                ll x = a[i + j], y = w * a[i + j + mid] % P;
                a[i + j] = (x + y) % P;
                a[i + j + mid] = (x - y + P) % P;
            }
        }
    }
}

inline void solve() {
    int lim = 1, k = 0;
    while (lim <= N + N) lim <<= 1, ++k;
    for (int i = 0; i < lim; ++i) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (k - 1));
    NTT(lim, A, 1);
    NTT(lim, B, 1);
    for (int i = 0; i < lim; ++i) A[i] = (A[i] * B[i]) % P;
    NTT(lim, A, -1);
    ll inv = fpow(lim, P - 2);
    for (int i = 0; i <= N + N; ++i) A[i] = A[i] * inv % P;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("sum.in", "r", stdin);
    freopen("sum.out", "w", stdout);
#endif
    N = ty();
    pre();
    solve();
    ll ans = 0, t = 1;
    for (int i = 0; i <= N; ++i, t = t * 2 % P) ans = (ans + t * fac[i] % P * A[i] % P) % P;
    printf("%lld\n", ans);
    return 0;
}

原文地址:https://www.cnblogs.com/newbielyx/p/12110691.html

时间: 2024-10-30 08:33:57

[HEOI2016/TJOI2016]求和 斯特林数 + NTT的相关文章

[HEOI2016/TJOI2016][bzoj4555] 求和 [斯特林数+NTT]

题面 传送门 思路 首先,我们发现这个式子中大部分的项都和\(j\)有关(尤其是后面的\(2^j\ast j!\)),所以我们更换一下枚举方式,把这道题的枚举方式变成先\(j\)再\(i\) \(f(n)=\sum_{j=0}^n2^j\ast j!\sum_{i=0}^nS_i^j\) 第二类斯特林数有一个基于组合意义的公式: \(S_i^j=\frac1{j!}\sum_{k=0}^j(-1)^kC_j^k(j-k)^i=\sum_{k=0}^j\frac{(-1)^k(j-k)^i}{k!

【BZOJ】4555: [Tjoi2016&amp;Heoi2016]求和 排列组合+多项式求逆 或 斯特林数+NTT

[题意]给定n,求Σi=0~nΣj=1~i s(i,j)*2^j*j!,n<=10^5. [算法]生成函数+排列组合+多项式求逆 [题解]参考: [BZOJ4555][Tjoi2016&Heoi2016]求和-NTT-多项式求逆 $ans=\sum_{i=0}^{n}\sum_{j=0}^{i}s(i,j)*2^j*j!$ 令$g(n)=\sum_{j=0}^{n}s(n,j)*2^j*j!$ 则ans是Σg(i),只要计算出g(i)的生成函数就可以统计答案. g(n)可以理解为将n个数划分

BZOJ4555 [Tjoi2016&amp;Heoi2016]求和 【第二类斯特林数 + NTT】

题目 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: S(i, j)表示第二类斯特林数,递推公式为: S(i, j) = j ? S(i ? 1, j) + S(i ? 1, j ? 1), 1 <= j <= i ? 1. 边界条件为:S(i, i) = 1(0 <= i), S(i, 0) = 0(1 <= i) 你能帮帮他吗? 输入格式 输入只有一个正整数 输出格式 输出f(n).由于结果会很大,输出f(n)对998244353(7

[HEOI2016/TJOI2016]求和——第二类斯特林数

给你斯特林数就换成通项公式,给你k次方就换成斯特林数 考虑换成通项公式之后,组合数没有什么好的处理方法 直接拆开,消一消阶乘 然后就发现了(j-k)和k! 往NTT方向靠拢 然后大功告成 其实只要想到把斯特林公式换成通项公式,考虑用NTT优化掉(j-k)^i 后面都是套路了. #include<bits/stdc++.h> #define reg register int #define il inline #define numb (ch^'0') #define int long long

[题解] LuoguP4091 [HEOI2016/TJOI2016]求和

传送门 首先我们来看一下怎么求\(S(m,n)\). 注意到第二类斯特林数的组合意义就是将\(m\)个不同的物品放到\(n\)个没有区别的盒子里,不允许有空盒子的方案数. 那么将\(m\)个不同的物品随便扔到\(n\)个盒子里的方案数就是\(n^m\),这里盒子也有区别了. 那么枚举有多少盒子有物品,然后斯特林数安排一下,注意到这是的盒子是没有区别的,再排列就好了,即 \[ n^m=\sum\limits_{i=0}^n \binom{n}{i}S(m,i)i! \] 但我们要求的是\(S\),

[HEOI2016/TJOI2016]求和

Discription 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: S(i, j)表示第二类斯特林数,递推公式为: S(i, j) = j ? S(i ? 1, j) + S(i ? 1, j ? 1), 1 <= j <= i ? 1. 边界条件为:S(i, i) = 1(0 <= i), S(i, 0) = 0(1 <= i) 你能帮帮他吗? Input 输入只有一个正整数 Output 输出f(n). 由于结果会很大,输出f(n

bzoj 5093 图的价值 —— 第二类斯特林数+NTT

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5093 每个点都是等价的,从点的贡献来看,得到式子: \( ans = n * \sum\limits_{d=0}^{n-1} d^{k} * 2^{C_{n-1}^{2}} * C_{n-1}^{d} \) 使用 \( n^{k} = \sum\limits_{i=0}^{k} S(k,i) * i! *C_{n}^{i} \) 得到 \( ans = n * \sum\limits_{d

bzoj5093:图的价值(第二类斯特林数+NTT)

传送门 首先,题目所求为\[n\times 2^{C_{n-1}^2}\sum_{i=0}^{n-1}C_{n-1}^ii^k\] 即对于每个点\(i\),枚举它的度数,然后计算方案.因为有\(n\)个点,且关于某个点连边的时候剩下的边都可以随便连,所以有前面的两个常数 所以真正要计算的是\[\sum_{i=0}^{n-1}C_{n-1}^ii^k\] 根据第二类斯特林数的性质,有\[i^k=\sum_{j=0}^iS(k,j)\times j!\times C_i^j\] 然后带入,得\[\s

P4091 [HEOI2016/TJOI2016]求和

留待警戒 FFT的时候长度要写的和函数里一样啊XD 瞎扯 这是个第二类斯特林数的理性愉悦颓柿子题目 颓柿子真的是让我hi到不行啦(才没有) 前置芝士 一个公式 \[ \sum_{i=0}^n t^i = \frac{t^{n+1}-1}{t-1} \] 第二类斯特林数 第二类斯特林数的是指把n个对象放到m个集合里面的方案数 其递推式是 \[ S_{n}^{m}=S_{n-1}^{m-1}+mS_{n-1}^{m} \] 容斥原理的得到的通式 \[ S_n^m=\frac{1}{m!}\sum_{