- 容斥原理: 将条件容斥
第一步: 先处理掉至少用一种颜色的: 设 f[i]表示用至多 i 种颜色, 每行每列都染色的格子的方案数/ 答案为 (-1)i * C{c}{i} f[c-i] 其中 i在[0..n] 中 : i为必须忽略的颜色
第二步: 求出 f[i]: (-1)k * C{m}{k} * ((i+1)k - 1)m 其中 k在[0..m] 中 : k为规定必须选的列数
点击查看代码
#include <stdio.h>
#include <string.h>
typedef long long LL;
const int N = 405, mod = 1e9 + 7;
int f[N], fac[N], inv[N];
int qpow(int b, int p) {
int res = 1;
while(p) {
if(p & 1) res = (LL)res * b % mod;
b = (LL)b * b % mod, p >>= 1;
} return res;
}
inline int C(int n, int m) {
if(n < m) return 0;
return (LL)fac[n] * inv[m] % mod * inv[n - m] % mod;
}
int n, m, c;
int main() {
scanf("%d%d%d", &n, &m, &c);
for(int i = fac[0] = inv[0] = 1; i <= m || i <= c; i ++)
fac[i] = (LL)fac[i - 1] * i % mod, inv[i] = qpow(fac[i], mod - 2);
for(int i = 1; i <= c; i ++) {
for(int k = 0; k <= m; k ++) {
int tmp = qpow((qpow(i + 1, m - k) - 1LL + mod) % mod, n);
if(k & 1) f[i] = (f[i] - (LL)tmp * C(m, k)) % mod;
else f[i] = (f[i] + (LL)tmp * C(m, k) + mod) % mod;
}
}
int res = 0;
for(int i = 0; i <= c; i ++)
if(i & 1) res = (res - (LL)C(c, i) * f[c - i] % mod) % mod;
else res = (res + (LL)C(c, i) * f[c - i] % mod + mod) % mod;
printf("%d\n", res);
return 0;
}