求 $\sum\limits_{i=0}^n\sum\limits_{j=0}^n Stirling2(i,j) \times 2^j \times j!$

$n \leq 100000$

sol:

小清新斯特林数多项式题

首先熟知斯特林数的卷积形式 $Stirling2(i,j) = \sum\limits_{k=0}^j \frac{(-1)^{(j-k)}}{(j-k)!} \times \frac{k^i}{k!}$

这题就是先对 $i$ 求个前缀和,再乘以 $2^j \times j!$ 再求和

于是卷积后一项的 $k^i \rightarrow \sum\limits_{i=0}^n k^i$

这是一个等比数列求和的形式,注意特判一下 $k=1$ 形式即可

然后就是套路啦,令 $A(x) = \frac{\sum\limits_{i=0}^n{k^i}}{k!} x$,$B(x)=\frac{(-1)^i}{i!}$,$C = A \times B$

则 $ans = \sum\limits_{i=0}^n 2^i \times i! \times [x^i]C(x)$

注意 $A(x),B(x),C(x)$ 的常数项都是 $1$

#include <bits/stdc++.h>
#define LL long long
#define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
#define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
using namespace std;
inline int read() {
int x = ,f = ; char ch = getchar();
for(; !isdigit(ch); ch = getchar())if(ch == '-') f = -f;
for(; isdigit(ch); ch = getchar())x = * x + ch - '';
return x * f;
}
const int maxn = , mod = ;
inline int inc(int x, int y) { x += y; if(x >= mod) x -= mod; return x; }
inline int dec(int x, int y) { x -= y; if(x < ) x += mod; return x; }
inline int mul(int x, int y) { return 1LL * x * y % mod; }
inline int ksm(int x, int t, int res = ) { for(; t; x = mul(x, x), t = t >> ) if(t & ) res = mul(res, x); return res; }
int n, a[maxn], b[maxn];
int r[maxn], lg[maxn], fac[maxn], ifac[maxn], pw[maxn];
void fft(int *a, int n, int f) {
rep(i, , n-) r[i] = (r[i >> ] >> ) | ((i & ) << (lg[n] - ));
rep(i, , n-) if(i < r[i]) swap(a[i], a[r[i]]);
for(register int i = ; i < n; i <<= ) {
int wn = ksm(, (mod - ) / (i << ));
if(f == -) wn = ksm(wn, mod - );
for(register int j = ; j < n; j += (i << )) {
int w = ;
for(register int k = ; k < i; k++, w = mul(w, wn)) {
int x = a[j + k], y = mul(w, a[j + k + i]);
a[j + k] = inc(x, y);
a[j + k + i] = dec(x, y);
}
}
}
if(f == -) {
int inv_n = ksm(n, mod - );
rep(i, , n - ) a[i] = mul(a[i], inv_n);
}
}
inline int cal(int x) {
if(x == ) return n + ;
else return mul(dec(ksm(x, n+), ), ksm(dec(x, ), mod - ));
}
int main() {
lg[] = -; rep(i, , maxn - ) lg[i] = lg[i >> ] + ;
n = read(); int len = ; for(; len <= (n<<); len <<= );
fac[] = ifac[] = ifac[] = pw[] = ; rep(i, , n) fac[i] = mul(fac[i - ], i);
rep(i, , n) ifac[i] = mul((mod - mod / i), ifac[mod % i]);
rep(i, , n) ifac[i] = mul(ifac[i], ifac[i - ]);
//cout << mul(ifac[3], fac[3]) << endl;
rep(i, , n) pw[i] = inc(pw[i - ], pw[i - ]);
a[] = b[] = ; rep(i, , n) a[i] = mul(cal(i), ifac[i]);
rep(i, , n) b[i] = (i & ) ? (mod - ifac[i]) : ifac[i];
fft(a, len, ); fft(b, len, );
//for(int i=0;i<len;i++) cout << a[i] << " "; cout << endl;
// for(int i=0;i<len;i++) cout << b[i] << " "; cout << endl;
rep(i, , len - ) a[i] = mul(a[i], b[i]);
// for(int i=0;i<len;i++) cout << a[i] << " "; cout << endl;
fft(a, len, -); int ans = ;
//for(int i=1;i<=n;i++) cout << a[i] << " "; cout << endl;
rep(i, , n) ans = inc(ans, mul(pw[i], mul(fac[i], a[i])));
cout << inc(ans, ) << endl;
}

还有一个小清新多项式求逆的做法

令 $f(n) = \sum\limits_{i=0}^n Stirling2(n,i) \times i! \times 2^i$,这个东西的组合意义为把 $n$ 个不同的物品放入若干个不同的集合中,且每个集合有两种不同的状态的方案数

枚举最后一个集合的大小和状态,得到 $f(n) = \sum\limits_{i=1}^n 2 \times \binom{n}{i} \times f(n-i)$

多项式求逆即可(远古代码

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = ,P = ,G = ;
int n,L,num,R[maxn],a[maxn],b[maxn],c[maxn],d[maxn];
int m;
int INV[maxn];
inline int ksm(int x,int t)
{
int res = ;
while(t)
{
if(t & ) res = 1LL * res * x % P;
x = 1LL * x * x % P;
t >>= ;
}
return res;
}
inline void NTT(int *a,int f,int n,int L)
{
for(int i=;i<n;i++) R[i] = (R[i>>] >> ) | ((i & ) << (L - ));
for(int i=;i<n;i++)if(i < R[i])swap(a[i],a[R[i]]);
for(int i=;i<n;i<<=)
{
int wn = ksm(G,(P - ) / (i << ));
if(f == -)wn = ksm(wn,P - );
for(int j=;j<n;j+=(i<<))
{
int w = ;
for(int k=;k<i;k++,w=1LL * w * wn % P)
{
int x = a[j + k], y = 1LL * w * a[j + k + i ] % P;
a[j + k] = ((x + y) % P + P) % P;
a[j + k + i] = ((x - y) % P + P) % P;
}
}
}
if(f == -)
{
int inv = ksm(n,P - );
for(int i=;i<n;i++)a[i] = 1LL * a[i] * inv % P;
}
}
inline void inverse(int *a,int *b,int n,int L)
{
if(n == ){b[] = ksm(a[],P - );return;}
inverse(a,b,n>>,L-);
memcpy(c,a,n*sizeof(int));memset(c+n,,n*sizeof(int));
NTT(c,,n<<,L+);NTT(b,,n<<,L+);
for(int i=;i<(n<<);i++) b[i] = 1LL * b[i] * (( - 1LL * c[i] * b[i] % P + P) % P) % P;
NTT(b,-,n<<,L+);memset(b+n,,n*sizeof(int));
}
int main()
{
scanf("%d",&n);
for(INV[] = INV[] = a[] = m=;m<=n;m<<=)L++;
for (int i=; i<=n; i++) INV[i]=P-(LL)INV[P%i]*(P/i)%P;
for (int i=; i<=n; i++) INV[i]=(LL)INV[i-]*INV[i]%P;
for (int i=; i<=n; i++) a[i]=((P-INV[i])<<)%P;
inverse(a,b,m,L);
int ans=b[n];
for (int i=n;i;i--) ans=((LL)ans*i+b[i-])%P;
printf("%d\n",ans);
return ;
}

bzoj 4555 求和的更多相关文章

  1. [BZOJ 4555][Tjoi2016&Heoi2016]求和

    题意 给定 $n$ , 求下式的值: $$ f(n)= \sum_{i=0}^n\sum_{j=0}^i\begin{Bmatrix}i\\ j\end{Bmatrix}\times 2^j\time ...

  2. BZOJ 4555 Luogu P4091 [HEOI2016/TJOI2016]求和 (第二类斯特林数)

    题目链接 (luogu) https://www.luogu.org/problem/P4091 (bzoj) https://www.lydsy.com/JudgeOnline/problem.ph ...

  3. BZOJ 4555: [Tjoi2016&Heoi2016]求和 [分治FFT 组合计数 | 多项式求逆]

    4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...

  4. BZOJ 4555: [Tjoi2016&Heoi2016]求和 [FFT 组合计数 容斥原理]

    4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...

  5. BZOJ 4555: [Tjoi2016&Heoi2016]求和 (NTT + 第二类斯特林数)

    题意 给你一个数 \(n\) 求这样一个函数的值 : \[\displaystyle f(n)=\sum_{i=0}^{n}\sum_{j=0}^{i} \begin{Bmatrix} i \\ j ...

  6. 【BZOJ 4555】 4555: [Tjoi2016&Heoi2016]求和 (NTT)

    4555: [Tjoi2016&Heoi2016]求和 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 315  Solved: 252 Des ...

  7. bzoj 4555 [Tjoi2016&Heoi2016] 求和 —— 第二类斯特林数+NTT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4555 关于第二类斯特林数:https://www.cnblogs.com/Wuweizhen ...

  8. BZOJ 4555 [Tjoi2016&Heoi2016]求和 (多项式求逆)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4555 题目大意: 给定 \(S(n,m)\) 表示第二类斯特林数,定义函数 \(f(n ...

  9. 【BZOJ 4555】[Tjoi2016&Heoi2016]求和 多项式求逆/NTT+第二类斯特林数

    出处0.0用到第二类斯特林数的性质,做法好像很多,我打的是直接ntt,由第二类斯特林数的容斥公式可以推出,我们可以对于每一个i,来一次ntt求出他与所有j组成的第二类斯特林数的值,这个时候我们是O(n ...

随机推荐

  1. 筛选最新生成的报告——sort

    筛选出最新报告发送,返回报告路径 import os def filePath(path): return os.path.join(os.path.abspath(os.path.dirname(o ...

  2. 使用Socket&反射&Java流操作进行方法的远程调用(模拟RPC远程调用)

    写在前面 阅读本文首先得具备基本的Socket.反射.Java流操作的基本API使用知识:否则本文你可能看不懂... 服务端的端口监听 进行远程调用,那就必须得有客户端和服务端.服务端负责提供服务,客 ...

  3. 一个linux命令(6/12):cat 命令

    cat主要有三大功能:1.一次显示整个文件.$ cat filename2.从键盘创建一个文件.$ cat > filename     只能创建新文件,不能编辑已有文件.3.将几个文件合并为一 ...

  4. mysql行列互相转换

    列转行: mysql> select * from test; +------+----------+-------+ | id | subject | score | +------+---- ...

  5. 【Thinking in java, 4e】复用类

    mark一篇09年的<Thinking in Java>笔记:here --> https://lawrence-zxc.github.io/2009/11/07/thinking- ...

  6. 验证环境中的program为什么必须是automatic

    最近在项目中,发现验证环境中的顶层的program(一般将program作为验证环境的入口),都是automatic的. 其实Program默认是static的,那么为什么需要把验证环境做成autom ...

  7. JavaWeb HTML

    1. HTML介绍 1.1. 什么是HTML HTML的全称为Hyper Text Markup Language,译为超文本标记语言. 超文本,就是指页面内可以包含图片.链接,甚至音乐.程序等非文字 ...

  8. PHP的date函数的时区问题

    来自:http://www.cnblogs.com/fuland/p/4250462.html(“腐烂的翅膀”的博客) 从php5.1.0开始,php.ini里加入了date.timezone这个选项 ...

  9. centos、linux查找未挂载磁盘格式化并挂载?

    centos.linux查找未挂载磁盘格式化并挂载? df -h 查看当前linux服务器硬盘: fdisk -l /dev/sda   第一块硬盘 /dev/sdb   第二块硬盘 依此类推 以/d ...

  10. Python 数据分析练习1

    环境 Anaconda3 Python 3.6, Window 64bit 目的 从MySQL数据库读取数据,进行数据清理,数据展示 代码 # -*- coding: utf-8 -*- import ...