BZOJ4487 [JSO12015] 染色问题 容斥原理

给出一个 n × m , n , m ≤ 4 e 2 n×m,n,m\leq4e2 n×m,n,m4e2的矩阵,并且有 c ≤ 4 e 2 c\leq4e2 c4e2种颜色,对于每一个小方格,你可以任选一个给它染色。给出条件:每个小方格可以被染色也可以不被染色,但是要求每一行每一列都至少有一个小方格要被染色。并且每种颜色都至少要出现一次,求总方案数。
考虑乘法原理和容斥原理,枚举没有被染色的行,没有被染色的列以及没有被用的颜色。 A n s = ∑ i = 0 n ∑ j = 0 m ∑ k = 0 c ( − 1 ) i + j + k C n i C m j C c k ( c − k + 1 ) ( n − i ) ( m − j ) Ans=\sum_{i=0}^{n}\sum_{j=0}^{m}\sum_{k=0}^{c}(-1)^{i+j+k}C_{n}^{i}C_{m}^{j}C_{c}^{k}(c-k+1)^{(n-i)(m-j)} Ans=i=0nj=0mk=0c(1)i+j+kCniCmjCck(ck+1)(ni)(mj)
考虑 c c c种颜色至少出现一次,就是 0 0 0种颜色没出现,考虑 F ( x ) F(x) F(x)是至少 x x x种颜色没出现。容斥 ∑ i = 0 c ( − 1 ) i C c i F ( i ) \sum_{i=0}^{c}(-1)^iC_{c}^{i}F(i) i=0c(1)iCciF(i)。此时可以得到最多出现 c − x c-x cx种颜色。
同理枚举 i i i行, j j j列可得答案。后面的式子是最多用 c − k c-k ck种颜色染 ( n − i ) (n-i) (ni)行, ( m − j ) (m-j) (mj)列的方案数。

#include
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=LONG_LONG_MAX;
const int N=4e2+7;
const int mod=1e9+7;
ll C[N][N]; 
ll f[N*N];
int main() {
	int n,m,c;
	scanf("%d%d%d",&n,&m,&c);
	for(int i=1;i<=400;i++) {
		C[i][0]=C[i][i]=1;
		for(int j=1;j

你可能感兴趣的:(比赛题解)