Atcoder题解:Agc002_f
我们可以把这个理解成一种类似卡塔兰数的形式,我们发现,被安排的
然后就可以
然后设
预处理阶乘和阶乘的逆元(如果暴力逆元可能
const ll P=1000000007;
ll fac[4000005],ifac[4000005],n,k;
inline ll fpow(ll a,ll p){
if(!p)return 1;
ll res=fpow(a,p>>1);
if(p&1)return res*res%P*a%P;
return res*res%P;
}
inline ll inv(ll a){
return fpow(a,P-2);
}
inline void init(){
fac[0]=1;ifac[0]=1;
for(int i=1;i<=4000000;i++)fac[i]=fac[i-1]*i%P;
for(int i=1;i<=4000000;i++)ifac[i]=ifac[i-1]*fac[i]%P;
ifac[4000000]=inv(ifac[4000000]);
for(int i=4000000;i>=1;i--){
int tmp=ifac[i];
ifac[i]=ifac[i]*ifac[i-1]%P;
ifac[i-1]=tmp*fac[i]%P;
}
}
inline ll C(int n,int m){
return fac[n]*ifac[m]%P*ifac[n-m]%P;
}
ll dp[2005][2005];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>k;
init();
if(k==1){
cout<<1<<endl;
return 0;
}
dp[0][0]=1;
for(int i=0;i<=n;i++){
for(int j=0;j<=i;j++){
if(i!=n){
dp[i+1][j]=(dp[i+1][j]+dp[i][j])%P;
}//n-(k-1)*j-i
if(j!=i){
dp[i][j+1]=(dp[i][j+1]+dp[i][j]*C(n*k-(k-1)*j-i-1,k-2)%P)%P;
}
}
}cout<<dp[n][n]*fac[n]%P<<endl;
return 0;
}
//Crayan_r
分类:
Atcoder题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统