斯特林数和下降幂

P5395 第二类斯特林数·行

给定n,对于所有的整数 i[0,n],你要求出 {ni}n2×105

做法是 NTT 卷积

{nm}=i=0mini!(1)mi(mi)!

如果你不知道哪里有卷积:

H(x)=F(x)G(x)H(x)=i=0n{ni}xiF(x)=i=0nini!xiG(x)=i=0n(1)ii!xi

点击查看代码
/*
* 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 幼儿园篮球题

只因你太美

我们要求的是

i=0kiL(mi)(nmki)(nk)

分母平凡,算分子,发现 iL 难搞,直接下降幂

i=0kiL(mi)(nmki)=i=0k(mi)(nmki)j=0i(ij)j!{Lj}=j=0kj!{Lj}i=jk(ij)(mi)(nmki)=j=0kj!{Lj}(mj)i=jk(mjij)(nmki)=j=0kj!{Lj}(mj)i=0kj(mji)(nmkij)=j=0kj!{Lj}(mj)(njkj)

NTT 卷积 O(LlogL) 求出 x[0,L]Z,{Lx}

我们发现最后的式子其实是

i=0min(k,m,L)i!{Li}(mi)(niki)

最终复杂度 O(LlogL+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。

posted @   ShaoJia  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示