简单斯特林反演

定义

定义 n k ‾ n^{\underline{k}} nk为n的k次下降幂,则 n k ‾ = n ⋅ ( n − 1 ) ⋅ . . . ⋅ ( n − k + 1 ) = n ! ( n − k ) ! = n ! k ! ( n − k ) ! k ! = ( k n ) k ! n^{\underline{k}}=n\cdot(n-1)\cdot...\cdot(n-k+1)=\frac {n!}{(n-k)!}=\frac {n!k!}{(n-k)!k!}=(^n_k)k! nk=n(n1)...(nk+1)=(nk)!n!=(nk)!k!n!k!=(kn)k!

定义 n k ‾ n^{\overline{k}} nk为n的k次上升幂,则 n k ‾ = n ⋅ ( n + 1 ) ⋅ . . . ⋅ ( n + k − 1 ) = ( n + k − 1 ) ! ( n − 1 ) ! = ( n + k − 1 ) ! k ! ( n − 1 ) ! k ! = ( k n + k − 1 ) k ! n^{\overline k}=n\cdot(n+1)\cdot...\cdot(n+k-1)=\frac{(n+k-1)!}{(n-1)!}=\frac{(n+k-1)!k!}{(n-1)!k!}=(^{n+k-1}_{k})k! nk=n(n+1)...(n+k1)=(n1)!(n+k1)!=(n1)!k!(n+k1)!k!=(kn+k1)k!

斯特林反演

斯特林反演揭示了上升幂,下降幂与普通幂的关系。

斯特林反演公式

  • 下降幂转普通幂
    x n ‾ = ∑ k = 0 n [ n k ] ( − 1 ) n − k x k x^{\underline n}=\overset{n}{\underset{k=0}\sum}\begin{bmatrix}n\\k\end{bmatrix}(-1)^{n-k}x^k xn=k=0n[nk](1)nkxk
  • 上升幂转普通幂
    x n ‾ = ∑ k = 0 n [ n k ] x k x^{\overline n}=\overset{n}{\underset{k=0}\sum}\begin{bmatrix}n\\k\end{bmatrix}x^k xn=k=0n[nk]xk
  • 普通幂转下降幂(常用)
    x n = ∑ k = 0 n { n k } x k ‾ = ∑ k = 0 n { n k } ( x k ) k ! x^n=\overset{n}{\underset{k=0}\sum}\begin{Bmatrix}n\\ k\end{Bmatrix}x^{\underline k}=\overset{n}{\underset{k=0}\sum}\begin{Bmatrix}n\\ k\end{Bmatrix}\begin{pmatrix}x\\ k\end{pmatrix}k! xn=k=0n{nk}xk=k=0n{nk}(xk)k!
  • 普通幂转上升幂
    x n = ∑ k = 0 n { n k } ( − 1 ) n − k x k ‾ = ∑ k = 0 n ( − 1 ) n − k { n k } ( x + k − 1 k ) k ! x^n=\overset{n}{\underset{k=0}\sum}\begin{Bmatrix}n\\ k\end{Bmatrix}(-1)^{n-k}x^{\overline k}=\overset{n}{\underset{k=0}\sum}(-1)^{n-k}\begin{Bmatrix}n\\ k\end{Bmatrix}\begin{pmatrix}x+k-1\\ k\end{pmatrix}k! xn=k=0n{nk}(1)nkxk=k=0n(1)nk{nk}(x+k1k)k!

事实上,必须说到,若有 n , k n,k n,k不合法,则斯特林数为 0 0 0,比如 n < k , n < 0 或 k < 0 n<k,n<0或k<0 n<k,n<0k<0
(你可能已经意识到了 ( k x ) k ! = A x k (^x_k)k!=A^k_x (kx)k!=Axk,但是为了方便处理,我们不这么写。)

启发

这两个式子一般在斯特林反演中不直接用到,但是可以给人启发:
组合恒等式: k ( n k ) = n ( n − 1 k − 1 ) k\begin{pmatrix}n\\k\end{pmatrix}=n\begin{pmatrix}n-1\\k-1\end{pmatrix} k(nk)=n(n1k1)
因而有: k x ‾ ( n k ) = n x ‾ ( n − x k − x ) k^{\underline{x}}\begin{pmatrix}n\\k\end{pmatrix}=n^{\underline x}\begin{pmatrix}n-x\\ k-x\end{pmatrix} kx(nk)=nx(nxkx)
因此我们注意到,在普通幂转下降幂的过程中,要选择原有组合数底项的次幂,作为转下降幂的对象。

证明

我们证明一下常用公式:
x n = ∑ k = 0 n { n k } x k ‾ = ∑ k = 0 n { n k } ( x k ) k ! x^n=\overset{n}{\underset{k=0}\sum}\begin{Bmatrix}n\\ k\end{Bmatrix}x^{\underline k}=\overset{n}{\underset{k=0}\sum}\begin{Bmatrix}n\\ k\end{Bmatrix}\begin{pmatrix}x\\ k\end{pmatrix}k! xn=k=0n{nk}xk=k=0n{nk}(xk)k!

组合意义:从组合意义上说,这个式子的成立是显然而明确的。

董老师的组合解释:
左边表示n个不同球放在x个不同盒子里,方案数显然有 x n x^n xn
右边表示枚举非空盒子的个数k,从x个盒子中选出k个盒子(组合数),把n个不同球放进去(斯特林数),对盒子做全排列。

我的组合解释:
左式表示有n个盒子,要往每个盒子里放一个小球,小球共有x种颜色的方案数。
右式表示的是,假设n个盒子已经放完了球,把放了颜色相同的球的盒子分为一组,总共有k组,现在指定这k组盒子分别放了什么颜色的球,首先从x种颜色中取出k种颜色作为用到的颜色,让颜色和盒子一一配对。注意到颜色和盒子是无关的,所以再对颜色做全排列。
(大雾)

然后还可以用数学归纳法证明。

事实上有:

  • 下降幂与普通幂的关系:
    在这里插入图片描述
  • 上升幂与普通幂的关系;
    在这里插入图片描述

证明就是直接拆开。

我们归纳常用公式,其他公式同理:
假设对于 x n − 1 x^{n-1} xn1符合归纳。
在这里插入图片描述
套一下刚才的式子:
在这里插入图片描述

注意到左式在 i = 0 i=0 i=0时等于 0 0 0,由于斯特林数为0。

QED.

其他归纳过程,有类似的证明。

例题

题目要求:
在这里插入图片描述
这个n实在是太高了,绝对不能留。

首先考虑把f带进去:
在这里插入图片描述

注意存在 k i k^i ki ( n k ) \begin{pmatrix}n\\ k\end{pmatrix} (nk),考虑对 k k k进行普通幂转下降幂:
在这里插入图片描述

注意到最后两个组合数构成分离式
在这里插入图片描述

越来越乱了,整理一下:
在这里插入图片描述
最后一个和式显然是二项式定理:
在这里插入图片描述

感觉可以做了?似乎。

注意到这个组合数不太好处理,当然用快速阶乘也不是处理不了…,继续拆一下式子:
在这里插入图片描述
这个形式看起来很好做了:

递推可以写出两项来对比一下。
在这里插入图片描述
然后就做完了。

#include<iostream>
using namespace std;
long long pow(long long a,long long b,long long c) {
	long long ans=1;
	while(b) {
		if(b&1) ans=ans*a%c;
		a=a*a%c;
		b>>=1;
	}
	return ans;
}
long long a[10005],J[10005],x[10005],f[10005];
int n,m;
long long M;
int s[10005][10005];
int main() {
	cin>>n>>x[1]>>M>>m;
	for(int i=0;i<=m;i++) cin>>a[i];
	x[0]=1;
	f[0]=pow(x[1]+1,n,M);
	for(int i=1;i<=m;i++)
		x[i]=x[i-1]*x[1]%M,
		f[i]=pow(x[1]+1,n-i,M);
	s[0][0]=1;
	for(int i=1;i<=m;i++)
		for(int j=1;j<=i;j++)
			s[i][j]=((long long)s[i-1][j-1]+(long long)j*s[i-1][j])%M;
	J[0]=1;
	for(int i=1;i<=m;i++)
		J[i]=J[i-1]*(n-i+1)%M;
	long long ans=0;
	for(int i=0;i<=m;i++) {
		long long sum=0;
		for(int j=0;j<=i;j++)
			(sum+=(long long)s[i][j]*J[j]%M*x[j]%M*f[j]%M)%=M;
		(ans+=a[i]*sum)%=M; 
	}
	cout<<ans;
	return 0;
}

习题
注意存在n<k的情况。

后记

于是皆大欢喜。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值