0
点赞
收藏
分享

微信扫一扫

bzoj 4487 [Jsoi2015]染色问题


4487: [Jsoi2015]染色问题
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 143 Solved: 85
[Submit][Status][Discuss]
Description

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

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

Input

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

Output

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

Sample Input

2 2 3

Sample Output

60

HINT

Source

【分析】
公式恐惧症+容斥原理

【代码】

//bzoj 4487 [Jsoi2015]染色问题 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mod=1e9+7;
const int mxn=405;
ll C[mxn][mxn];
ll n,m,c,f,ans;
inline ll ksm(ll x,ll k)
{
    if(k==0) return 1;
    if(k==1) return x;
    ll tmp=ksm(x,k>>1);
    if(k&1) return tmp*tmp%mod*x%mod;
    return tmp*tmp%mod;
}
inline void init()
{
    int i,j;
    fo(i,0,400) C[i][0]=1;
    fo(i,1,400)
      fo(j,1,i)
        C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
}
int main()
{
    int i,j,k;
    init();
    scanf("%d%d%d",&n,&m,&c);
    fo(i,0,n)
      fo(k,0,c)
      {
          if(i+k&1) f=-1;else f=1;
          f=f*C[n][i]%mod*C[c][k]%mod;
          ll now=ksm((ll)c-k+1,(ll)n-i)%mod;
          now=ksm((now-1)%mod,m);
          f=f*now%mod;
          ans=(ans+f)%mod;
      }
    printf("%lld\n",(ans+mod)%mod);
    return 0;
}


举报

相关推荐

0 条评论