题解:P10005 [集训队互测 2023] 基础寄术练习题
ini2015_____ · · 题解
zfr 感觉比较平凡,但是我做不出来,呜呜呜。
发现
考虑 P5644 的组合意义,相当于每次选择一个人删掉,删掉第
这样我们可以轻易做
考虑
诶看看怎么刻画一个人最后被删掉的概率。诶这不就是 P5644 吗,直接搬过来,钦定一个集合
然后你就 DP 嘛,记
发现
时间复杂度
const int N=1e2+5,inf=1e9+7;
int n,m,k,mod;
int fpow(int a,int b){
int res=1;
for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)res=1ll*a*res%mod;
return res;
}
inline void upd(int& x){if(x>=mod)x-=mod;}
int iv[N*N];
void initfac(){for(int i=1;i<N*N;i++)iv[i]=fpow(i,mod-2);}
int g[N];
void solve1(){
g[0]=1;
for(int i=1;i<=m;i++)for(int j=n;j;j--)upd(g[j]+=1ll*g[j-1]*iv[i]%mod);
printf("%d\n",g[n]);
}
int f[2][N*N][N][2];
void solve2(){
f[0][0][0][0]=1;
for(int i=1,o=1;i<=m;i++,o^=1){
memset(f[o],0,sizeof f[o]);
for(int j=0;j<=n*m;j++)for(int k=0;k<=n;k++)for(int l:{0,1}){
int v=f[o^1][j][k][l];
if(!v)continue;
upd(f[o][j+i][k+1][l]+=1ll*(mod-v)*iv[i]%mod);
upd(f[o][j][k][l]+=v);
upd(f[o][j][k+1][l]+=1ll*v*iv[i]%mod);
if(!l)upd(f[o][j+i][k+1][1]+=1ll*i*v%mod);
}
}
int o=m&1,ans=0;
for(int i=1;i<=n*m;i++)
upd(ans+=1ll*f[o][i][n][1]*iv[i]%mod);
printf("%d\n",ans);
}
int main(){
n=read(),m=read(),k=read(),mod=read();
initfac();
if(k==1)solve1();
if(k==2)solve2();
return 0;
}
// Think twice,code once
::::