斯特林数和下降幂
P5395 第二类斯特林数·行
给定\(n\),对于所有的整数 \(i\in[0,n]\),你要求出 \({n\brace i}\),\(n\le 2\times 10^5\)。
做法是 NTT 卷积
\[{n\brace m}=\sum_{i=0}^m \frac{i^n}{i!}\frac{(-1)^{m-i}}{(m-i)!}
\]
如果你不知道哪里有卷积:
\[\begin{aligned}
\\H(x)&=F(x)G(x)
\\H(x)&=\sum_{i=0}^n{n\brace i}x^i
\\F(x)&=\sum_{i=0}^n\frac{i^n}{i!}x^i
\\G(x)&=\sum_{i=0}^n\frac{(-1)^i}{i!}x^i
\end{aligned}
\]
点击查看代码
/*
* Author: ShaoJia
* Last Modified time: 2022-10-06 21:42:02
* Motto: We'll be counting stars.
*/
// #pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define debug(...) cerr<<"#"<<__LINE__<<": "<<__VA_ARGS__<<endl
#define For(i,j,k) for(int i=(j),i##_=(k);i<=i##_;i++)
#define Rof(i,j,k) for(int i=(j),i##_=(k);i>=i##_;i--)
#define lob lower_bound
#define upb upper_bound
#define fir first
#define sec second
#define mkp make_pair
#define siz(x) ((int)(x).size())
#define pb emplace_back
#define ckmx(a,b) a=max(a,b)
#define ckmn(a,b) a=min(a,b)
#define ll long long
#define pi pair<int,int>
const int N=1<<19;
const ll mod=167772161;
ll pw(ll x,ll y){
ll res=1;
while(y){
if(y&1){
(res*=x)%=mod;
}
y>>=1;
(x*=x)%=mod;
}
return res;
}
ll f[N],ivf[N],F[N],G[N],st[N],w[N];
int n,lim,B=0,tax[N];
void mktw(){
tax[0]=0;
For(i,1,lim-1) tax[i]=(tax[i>>1]>>1)|((i&1)<<(B-1));
ll wn=pw(3,(mod-1)/lim);
w[0]=1;
For(i,1,lim-1) w[i]=w[i-1]*wn%mod;
}
void DFT(ll *a){
For(i,0,lim-1) if(i<tax[i]) swap(a[i],a[tax[i]]);
ll x,y;
for(int len=2;len<=lim;len<<=1){
for(int i=0;i<lim;i+=len){
For(j,0,(len>>1)-1){
x=a[i+j];
y=a[i+j+(len>>1)]*w[lim/len*j]%mod;
a[i+j]=(x+y)%mod;
a[i+j+(len>>1)]=(x-y+mod)%mod;
}
}
}
}
void IDFT(ll *a){
ll x=pw(lim,mod-2);
reverse(a+1,a+lim);
DFT(a);
For(i,0,lim-1) (a[i]*=x)%=mod;
}
signed main(){ios::sync_with_stdio(false),cin.tie(nullptr);
cin>>n;
f[0]=1; For(i,1,n) f[i]=f[i-1]*i%mod;
ivf[n]=pw(f[n],mod-2); Rof(i,n,1) ivf[i-1]=ivf[i]*i%mod;
For(i,0,n) F[i]=pw(i,n)*ivf[i]%mod;
For(i,0,n) G[i]=(i&1?mod-1:1)*ivf[i]%mod;
while((1<<B)<=2*n) B++;
lim=1<<B;
mktw(),DFT(F),DFT(G);
For(i,0,lim-1) st[i]=F[i]*G[i]%mod;
IDFT(st);
For(i,0,n) cout<<st[i]<<" "; cout<<"\n";
return 0;}
P2791 幼儿园篮球题
只因你太美
我们要求的是
\[\frac{\sum_{i=0}^ki^L\binom{m}{i}\binom{n-m}{k-i}}{\binom{n}{k}}
\]
分母平凡,算分子,发现 \(i^L\) 难搞,直接下降幂
\[\begin{aligned}
&\sum_{i=0}^ki^L\binom{m}{i}\binom{n-m}{k-i}
\\=&\sum_{i=0}^k\binom{m}{i}\binom{n-m}{k-i}\sum_{j=0}^i\binom{i}{j}j!{L\brace j}
\\=&\sum_{j=0}^kj!{L\brace j}\sum_{i=j}^k\binom{i}{j}\binom{m}{i}\binom{n-m}{k-i}
\\=&\sum_{j=0}^kj!{L\brace j}\binom{m}{j}\sum_{i=j}^k\binom{m-j}{i-j}\binom{n-m}{k-i}
\\=&\sum_{j=0}^kj!{L\brace j}\binom{m}{j}\sum_{i=0}^{k-j}\binom{m-j}{i}\binom{n-m}{k-i-j}
\\=&\sum_{j=0}^kj!{L\brace j}\binom{m}{j}\binom{n-j}{k-j}
\end{aligned}
\]
NTT 卷积 \(O(L\log L)\) 求出 \(\forall x\in[0,L]\cap\mathbb{Z},{L\brace x}\)。
我们发现最后的式子其实是
\[\sum_{i=0}^{\min(k,m,L)}i!{L\brace i}\binom{m}{i}\binom{n-i}{k-i}
\]
最终复杂度 \(O(L\log L+SL)\)(\(S\) 是数据组数),略卡空间。
点击查看代码
/*
* Author: ShaoJia
* Last Modified time: 2022-10-06 21:12:45
* Motto: We'll be counting stars.
*/
// #pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define debug(...) cerr<<"#"<<__LINE__<<": "<<__VA_ARGS__<<endl
#define For(i,j,k) for(int i=(j),i##_=(k);i<=i##_;i++)
#define Rof(i,j,k) for(int i=(j),i##_=(k);i>=i##_;i--)
#define lob lower_bound
#define upb upper_bound
#define fir first
#define sec second
#define mkp make_pair
#define siz(x) ((int)(x).size())
#define pb emplace_back
#define ckmx(a,b) a=max(a,b)
#define ckmn(a,b) a=min(a,b)
#define ll long long
#define pi pair<int,int>
const ll mod=998244353;
const int N=1<<19,V=20000001;
ll pw(ll x,ll y){
ll res=1;
while(y){
if(y&1){
(res*=x)%=mod;
}
y>>=1;
(x*=x)%=mod;
}
return res;
}
int n,m,k,L,B,lim,tax[N],f[V],ivf[V];//f & ivf longlong MLE
ll F[N],G[N],st[N],w[N];
void mktw(){
tax[0]=0;
For(i,1,lim-1) tax[i]=(tax[i>>1]>>1)|((i&1)<<(B-1));
ll wn=pw(3,(mod-1)/lim);
w[0]=1;
For(i,1,lim-1) w[i]=w[i-1]*wn%mod;
}
void DFT(ll *a){
For(i,0,lim-1) if(i<tax[i]) swap(a[i],a[tax[i]]);
ll x,y;
for(int len=2;len<=lim;len<<=1){
for(int i=0;i<lim;i+=len){
For(j,0,(len>>1)-1){
x=a[i+j];
y=a[i+j+(len>>1)]*w[lim/len*j]%mod;
a[i+j]=(x+y)%mod;
a[i+j+(len>>1)]=(x-y+mod)%mod;
}
}
}
}
void IDFT(ll *a){
ll x=pw(lim,mod-2);
reverse(a+1,a+lim);
DFT(a);
For(i,0,lim-1) (a[i]*=x)%=mod;
}
void init(){
f[0]=1;
For(i,1,V-1) f[i]=1ll*f[i-1]*i%mod;
ivf[V-1]=pw(f[V-1],mod-2);
Rof(i,V-1,1) ivf[i-1]=1ll*ivf[i]*i%mod;
For(i,0,L) F[i]=pw(i,L)*ivf[i]%mod;
For(i,0,L) G[i]=(i&1?mod-1:1ll)*ivf[i]%mod;
B=0;
while((1<<B)<=2*L) B++;
lim=1<<B;
mktw();
DFT(F);
DFT(G);
For(i,0,lim-1) st[i]=F[i]*G[i]%mod;
IDFT(st);
// For(i,0,L) cout<<st[i]<<"*"; cout<<"\n";
}
ll C(ll x,ll y){ return 1ll*f[x]*ivf[y]%mod*ivf[x-y]%mod; }
ll iC(ll x,ll y){ return 1ll*ivf[x]*f[y]%mod*f[x-y]%mod; }
void work(){
cin>>n>>m>>k;
int tot=min({k,m,L});
ll ans=0;
For(i,0,tot) (ans+=f[i]*st[i]%mod*C(m,i)%mod*C(n-i,k-i))%=mod;
cout<<ans*iC(n,k)%mod<<"\n";
}
signed main(){ios::sync_with_stdio(false),cin.tie(nullptr);
int T;cin>>n>>m>>T>>L;
init();while(T--)work();
return 0;}
CF1528F AmShZ Farm
后面部分就是 第二类斯特林数·行,前面部分见 2023sol2。
本文来自博客园,作者:ShaoJia,版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。