题解 网格染色 容斥

题解 网格染色

题目描述

有一个 n × m n \times m n×m的网格,可以给任意多个格子染色,问要使得每行每列都至少有一个格子被染色有多少种方案?

具体做法与心路历程

考试时也想怎么容斥,想法是先每行考虑,再每列考虑,最后在减去多了的。还是容斥题做少了,这种明显的 1 , − 1 1,-1 1,1容斥都没做出。

具体做法

题目有两个大的限制条件:行,列。如果我们同时考虑两个不好做,那么只先考虑一个。

因为直接求方案不方便,所以我们利用补集转化: 合 法 方 案 = 总 方 案 − 非 法 方 案 合法方案=总方案-非法方案 =

先不管行,考虑列。

那么总方案为每一列都合法的方案数,非法的方案即为列合法行不合法的方案数

总方案数= ( 2 n − 1 ) m (2^{n}-1)^m (2n1)m,每一列有 n n n个数,每个数可选可不选,那么这一列就有 2 n 2^{n} 2n种方案,除去全不选的一种方案再利用乘法原理求出所有方案即可。

重点在怎么求非法方案数,这个应该利用 1 , − 1 1,-1 1,1容斥来进行

非法方案数=至少有某一行不合法的方案数-至少有某两行不合法的方案数+至少有某三行不合法的方案数…

写成式子为
∑ i = 1 N ( − 1 ) i ( n i ) ( 2 n − i − 1 ) m \sum\limits_{i=1}^N (-1)^i \begin{pmatrix} n \\ i \end{pmatrix}(2^{n-i} - 1)^m i=1N(1)i(ni)(2ni1)m
这样问题就解决了。

C o d e \mathcal{Code} Code

/*******************************
Author:galaxy yr
LANG:C++
Created Time:2019年10月25日 星期五 20时17分09秒
*******************************/
#include<iostream>
#include<cstdio>
#include<string>

using namespace std;

const int maxn=1e6+10;
const int mod=998244353;
long long n,m,fac[maxn],ifac[maxn],inv[maxn],f[maxn],ans;

void init()
{
    fac[0]=fac[1]=ifac[0]=ifac[1]=inv[0]=inv[1]=1;
    int n=1e6;
    for(int i=2;i<=n;i++)
        fac[i]=fac[i-1]*i%mod,inv[i]=(mod-mod/i)*inv[mod%i]%mod,ifac[i]=ifac[i-1]*inv[i]%mod;
}

long long C(int n,int m)
{
    return fac[n]*ifac[m]%mod*ifac[n-m]%mod;
}

long long ksm(long long a,long long b)
{
    long long res=1;
    while(b)
    {
        if(b&1)
            res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}

int main()
{
    //freopen("box.in","r",stdin);
    //freopen("box.out","w",stdout);
    cin>>n>>m;
    init();
    for(int i=1;i<=m;i++)
        f[i]=C(m,i)*ksm(ksm(2,i)-1,n)%mod;
    for(int i=m;i>=1;i--)
        if((m-i+1)&1) 
            ans=(ans+f[i])%mod;
        else
            ans=(ans-f[i]+mod)%mod;
    printf("%lld\n",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值