【bzoj4487】[Jsoi2015]染色问题 容斥原理

题目描述

棋盘是一个n×m的矩形,分成n行m列共n*m个小方格。现在萌萌和南南有C种不同颜色的颜料,他们希望把棋盘用这些颜料染色,并满足以下规定: 
1.  棋盘的每一个小方格既可以染色(染成C种颜色中的一种) ,也可以不染色。 
2.  棋盘的每一行至少有一个小方格被染色。 
3.  棋盘的每一列至少有一个小方格被染色。 
4.  种颜色都在棋盘上出现至少一次。 
以下是一些将3×3棋盘染成C = 3种颜色(红、黄、蓝)的例子:

请你求出满足要求的不同的染色方案总数。只要存在一个位置的颜色不同,即认为两个染色方案是不同的

输入

输入只有一行 3 个整数 n,m,c 。1 < = n,m,c < = 400

输出

输出一个整数,为不同染色方案总数。因为总数可能很大,只需输出总数
mod 1,000,000,007的值。

样例输入

2 2 3

样例输出

60



题解

容斥原理

题目要求:所有行都有格子被染色、所有列都有格子被染色、所有颜色都有格子被染色的方案数。

我们可以容斥一下,求:有 $i$ 行没有格子被染色、有 $j$ 列没有格子被染色、有 $k$ 种颜色没有格子被染色的方案数。

那么答案为 $\sum\limits_{i=0}^n\sum\limits_{j=0}^m\sum\limits_{k=0}^c(-1)^{i+j+k}C_n^iC_m^jC_c^k((n-i)(m-j))^k$ 。

由于 $n,m,c$ 都只有400,因此不需要做进一步推导,直接预处理组合数+幂,暴力计算即可。

时间复杂度 $O(n^3)$

#include <cstdio>
#include <algorithm>
#define mod 1000000007
using namespace std;
typedef long long ll;
ll c[410][410] , pow[160010];
int main()
{
	int n , m , p , i , j , k;
	ll ans = 0;
	scanf("%d%d%d" , &n , &m , &p);
	pow[0] = c[0][0] = 1;
	for(i = 1 ; i <= n || i <= m || i <= p ; i ++ )
	{
		c[i][0] = 1;
		for(j = 1 ; j <= i ; j ++ )
			c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
	}
	for(i = 0 ; i <= p ; i ++ )
	{
		for(j = 1 ; j <= n * m ; j ++ ) pow[j] = pow[j - 1] * (p - i + 1) % mod;
		for(j = 0 ; j <= n ; j ++ )
			for(k = 0 ; k <= m ; k ++ )
				ans = (ans + c[p][i] * c[n][j] % mod * c[m][k] % mod * pow[(n - j) * (m - k)] % mod * ((i ^ j ^ k) & 1 ? -1 : 1) + mod) % mod;
	}
	printf("%lld\n" , ans);
	return 0;
}

原文地址:https://www.cnblogs.com/GXZlegend/p/8297567.html

时间: 2024-07-30 15:49:20

【bzoj4487】[Jsoi2015]染色问题 容斥原理的相关文章

4487[Jsoi2015]染色问题 容斥+组合

4487: [Jsoi2015]染色问题 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 211  Solved: 127[Submit][Status][Discuss] Description 棋盘是一个n×m的矩形,分成n行m列共n*m个小方格.现在萌萌和南南有C种不同颜色的颜料,他们希望把棋盘用这些颜料染色,并满足以下规定:1.  棋盘的每一个小方格既可以染色(染成C种颜色中的一种) ,也可以不染色.2.  棋盘的每一行至少有一个小方格被染

bzoj 4487: [Jsoi2015]染色问题

先贴一个题解吧,最近懒得要死2333,可能是太弱的原因吧,总是扒题解,(甚至连题解都看不懂了),blog也没更新,GG http://blog.csdn.net/werkeytom_ftd/article/details/52527740 容斥原理真的很神奇233 1 #include <bits/stdc++.h> 2 #define LL long long 3 using namespace std; 4 5 const int maxn=500; 6 const int mod=1e9

luoguP4491 [HAOI2018]染色 广义容斥原理 + FFT

非常明显的摆了一个NTT模数.... 题目中求恰好\(k\),那么考虑求至少\(k\) 记\(g(k)\)表示至少\(k\)中颜色出现了恰好\(S\)次 那么,\[g(k) = \binom{M}{k} \frac{N!}{(S!)^k (N-Sk)!} * (M-k)^{N-Sk}\] 根据广义容斥原理,记\(f(i)\)表示恰好\(k\)种颜色出现了恰好\(k\)次 那么,\[f(i) = \sum \limits_{k = i}^M (-1)^{k - i} \binom{k}{i} g(

[Jsoi2015]染色问题

题目 看到这个限制条件有点多,我们就一直容斥好了 先容斥颜色,我们枚举至少不用\(i\)种颜色 再容斥列,我们枚举至少不用\(j\)列 最后容斥行,枚举至少不用\(k\)行 容斥系数显然是\((-1)^i,(-1)^j,(-1)^k\),我们从\(c\)种颜色里选出\(i\)种不用,\(m\)列里选出\(j\)列不凃,\(n\)行里选出\(k\)行不凃,分别是\(\binom{c}{i},\binom{m}{j},\binom{n}{k}\) 对于剩下的\((m-j)(n-k)\)个格子,每个格

【题解】方块染色(容斥原理+巧妙分类)

[题解]方块染色(容斥原理+巧妙分类) 刚开始以为是道容斥,写了这个错误程序 int main(){ pre(1e5); while(~scanf("%d%d",&n,&m)){ int ans=0; for(register int t=m,delta;t<=n;++t){ delta=0; for(register int k=1,d2;k<=n/t;++k){ d2=1ll*c(n/t,k)*(n-k*t+1)%mod*bin[n-k*t]%mod;

[HAOI2018][bzoj5306] 染色 [容斥原理+NTT]

广告 蒟蒻のblog 思路 这道题的核心在于"恰好有\(k\)种颜色占了恰好\(s\)个格子" 这些"恰好",引导我们去思考,怎么求出总的方案数呢? 分开考虑 考虑把恰好有\(s\)个格子的颜色,和不是\(s\)个颜色的格子分开来考虑 那么,显然答案可以用这样的一个式子表示: 令\(lim=min(\lfloor\frac ns\rfloor,m)\),那么: \(ans=\sum_{i=0}^{lim}w_iC_m^iC_n^{is}\frac{(is)!}{(s

CF GYM100548 (相邻格子颜色不同的方案数 2014西安区域赛F题 容斥原理)

n个格子排成一行,有m种颜色,问用恰好k种颜色进行染色,使得相邻格子颜色不同的方案数. integers n, m, k (1 ≤n, m ≤ 10^9, 1 ≤ k ≤ 10^6, k ≤ n, m). m种颜色取k种 C(m, k) 这个可以放最后乘 那么问题就变成只用k种颜色第一个格子有k种涂法 第二个有k-1种 第三个也是k-1种 一共就是k*(k-1)^(n-1) 这种算法仅保证了相邻颜色不同,总颜色数不超过k种,并没有保证恰好出现k种颜色 也就是多算了恰好出现2种 恰好出现3种...

几个解决k染色问题的指数级做法

几个解决k染色问题的指数级做法 ——以及CF908H题解 给你一张n个点的普通无向图,让你给每个点染上k种颜色中的一种,要求对于每条边,两个端点的颜色不能相同,问你是否存在一种可行方案,或是让你输出一种可行方案,或是让你求出满足条件的最小的k.这种问题叫做k染色问题.众所周知,当k>2时,k染色问题是NP的.但是相比$O(k^n)$的暴力搜索来说,人们还是找到了很多复杂度比较优越的指数级做法.本文简单介绍其中几种. 因为对于$O(n^22^n)$来说,$O(n^2)$小得可以忽略不计,所以在本文

P4491 [HAOI2018]染色

传送门 我觉得自己的数学也是够差的--一点思路也没有-- 考虑容斥,首先\(lim=min(m,n/S)\),设\(f[i]\)表示出现恰好\(S\)次的元素大于等于\(i\)种的情况,我们随便选\(i\)种颜色放\(S\)次,选的方法数有\(C_m^i\)种,然后染色可以看做是一个类似全排列的东西,每连续的几个染上同样的颜色,那么方案数为\(\frac{n!}{(S!)^i(n-S*i)!}\),前面颜色已经选定了,后面的每个有\(m-i\)种颜色可选,所以还要乘上一个\((m-i)^{n-S