(m)种颜色,(n)层,给每层(l_i)个位置涂色,要求相邻位置颜色不同,相邻层数颜色集合也不能相同,求方案数
考虑在一行内彩球的方案数,(g[i][j])表示一共(i)个球串成一行,共用(j)种颜色的方案数
类似最小表示法简化计数,强制令其有序,实际方案数为(g[i][j]*j!)
若前(i-1)个球使用了(j-1)种颜色,则第(i)个球必然使用了第(j)种颜色;若前(i-1)个球已使用了(j)种颜色,则第(i)个球使用的颜色必须与第(i-1)个球不同,所以有((j-1))种方案
(g[i][j]=g[i-1][j-1]+(j-1)g[i-1][j])
考虑行与行的影响
(f[i][j])表示前(i)层恰用了(j)种颜色
若不考虑两层之间颜色集合需不同
(f[i][j]=A_m^j*g[l[i]][j]*sum f[i-1][k])
减去不合法
(f[i][j]=A_m^j*g[l[i]][j]*sum f[i-1][k]-f[i-1][j]*g[l[i]][j]*j!)
ll n,m,mod,maxx,l[2000005],A[M],fac[M],f[5005][5005],g[2][5010];
int main(){
scanf("%lld%lld%lld",&n,&m,&mod); fac[0] = A[0] = f[0][0] = 1;
for(int i = 1;i <= n;++i) l[i] = read(),maxx = max(maxx,l[i]);
for(int i = 1;i <= maxx;++i) A[i] = A[i-1] * (m-i+1) % mod;
for(int i = 1;i <= maxx;++i) fac[i] = fac[i-1] * i % mod;
for(int i = 1;i <= maxx;++i)
for(int j = 1;j <= i && j <= m;++j)
f[i][j] = (f[i-1][j-1] + f[i-1][j]*(j-1)) % mod;
ll ans = 1,sum = 0;
for(int i = 1;i <= n;++i){
for(int j = 1;j <= l[i];++j){
ll tmp = (A[j]*ans - g[i&1^1][j]*fac[j]) % mod;
g[i & 1][j] = f[l[i]][j] * tmp % mod;
sum += g[i & 1][j];
}
ans = (sum % mod + mod) % mod; sum = 0;
memset(g[i&1^1],0,sizeof(g[0]));
}
printf("%lld",ans);
}