HDU6314: Matrix 题解

本文介绍了一种利用广义容斥原理解决矩阵染色问题的方法。通过计算至少指定行和列全黑的矩阵染色方案数,最终解决了计数问题,并提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

Samwell Tarly is learning to draw a magical matrix to protect himself from the White Walkers.
the magical matrix is a matrix with n rows and m columns, and every single block should be painted either black or white.
Sam wants to know how many ways to paint the matrix, satisfied that the final matrix has at least A rows, B columns was painted completely black. Cause the answer might be too big, you only need to output it modulo 998244353.

Input

There might be multiple test cases, no more than 5. You need to read till the end of input.
For each test case, a line containing four integers n,m,A,B.
1≤n,m,A,B≤3000.

Output

For each test case, output a line containing the answer modulo 998244353.

Sample Input

3 4 1 2

Sample Output

169

Source

2018 Multi-University Training Contest 2


以前没有做过广义容斥的题目,今天算是学习了
有看到一篇栋爷的不错的文章,戳这
回到这题,我们先把列丢掉,记 Ans(a) A n s ( a ) 表示至少有a行全黑的方案数,那么考虑容斥,有以下式子

Ans(a)=i=anfa,iCin(i) A n s ( a ) = ∑ i = a n f a , i C n i ∗ ( 选 出 的 i 行 全 黑 的 方 案 数 )

这里的 fa,i f a , i Ans(a) A n s ( a ) 所对应的一个未知的容斥系数
我们考虑怎么求 f f
我们考虑任意一个选了i行且这 i i 行全黑的方案,看看在上面的式子里它被计算了多少次
可以容易的算出次数,又因为每个方案最后应该只被算一次,所以可以列出等式
j=aiCijfa,j=1

我们尝试推导 fa,i f a , i 的递推式
i=an+1Cjn+1fa,i=i=anCin+1fa,i+fn+1=i=an(Ci1n+Cin)fa,i+fn+1=i=anCinfa,i+i=anCi1nfa,i+fn+1=1+i=anCi1nfa,i+fn+1=1 ∑ i = a n + 1 C n + 1 j f a , i = ∑ i = a n C n + 1 i f a , i + f n + 1 = ∑ i = a n ( C n i − 1 + C n i ) f a , i + f n + 1 = ∑ i = a n C n i f a , i + ∑ i = a n C n i − 1 f a , i + f n + 1 = 1 + ∑ i = a n C n i − 1 f a , i + f n + 1 = 1

所以
fn+1=i=anCi1nfa,i f n + 1 = − ∑ i = a n C n i − 1 f a , i

这样我们可以在 O(n2) O ( n 2 ) 的时间内递推出容斥系数
我们发现列的问题和行的问题是等价的,所以相同的容斥系数的推法可以直接套用上去
我们考虑 Ans(a,b) A n s ( a , b ) 表示至少a行和b列全黑的方案数,则有
Ans(a,b)=i=anj=bmCinfa,iCjmfb,j(ij) A n s ( a , b ) = ∑ i = a n ∑ j = b m C n i f a , i C m j f b , j ∗ ( 选 中 的 i 行 j 列 全 黑 的 方 案 数 )

最后括号里的这个东西显然等于 2(ni)(mj) 2 ( n − i ) ( m − j ) ,于是就做完了

#include <bits/stdc++.h>
using namespace std;

#define LL long long
#define LB long double
#define ull unsigned long long
#define x first
#define y second
#define pb push_back
#define pf push_front
#define mp make_pair
#define Pair pair<int,int>
#define pLL pair<LL,LL>
#define pii pair<double,double>

const int INF=2e9;
const LL LINF=2e16;
const int magic=348;
const int MOD=998244353;
const double eps=1e-10;
const double pi=acos(-1);

inline int getint()
{
    bool f;char ch;int res;
    while (!isdigit(ch=getchar()) && ch!='-') {}
    if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
    while (isdigit(ch=getchar())) res=res*10+ch-'0';
    return f?res:-res;
}

const int MAXN=3000;

inline int add(int x) {if (x>=MOD) x-=MOD;return x;}
inline int sub(int x) {if (x<0) x+=MOD;return x;}

int c[MAXN+48][MAXN+48];
inline void init_c()
{
    int i,j;c[0][0]=1;
    for (i=1;i<=MAXN;i++)
    {
        c[i][0]=c[i][i]=1;
        for (j=1;j<=i-1;j++)
            c[i][j]=add(c[i-1][j-1]+c[i-1][j]);
    }
}

int pw[MAXN*MAXN+48];
inline void init_pw()
{
    pw[0]=1;
    for (register int i=1;i<=MAXN*MAXN;i++) pw[i]=add(pw[i-1]+pw[i-1]);
}

int n,m,A,B;
int fa[MAXN+48],fb[MAXN+48];
inline void init_f()
{
    int i,j;
    fa[A]=1;
    for (i=A+1;i<=n;i++)
    {
        fa[i]=0;
        for (j=A;j<=i-1;j++)
            fa[i]=sub(fa[i]-(1ll*c[i-1][j-1]*fa[j])%MOD);
    }
    fb[B]=1;
    for (i=B+1;i<=m;i++)
    {
        fb[i]=0;
        for (j=B;j<=i-1;j++)
            fb[i]=sub(fb[i]-(1ll*c[i-1][j-1]*fb[j])%MOD);
    }
}

int main ()
{
    init_c();init_pw();int i,j;
    while (scanf("%d%d%d%d",&n,&m,&A,&B)!=EOF)
    {
        init_f();int ans=0;
        for (i=A;i<=n;i++)
            for (j=B;j<=m;j++)
                ans=add(ans+((((1ll*fa[i]*fb[j])%MOD*c[n][i])%MOD*c[m][j])%MOD*pw[(n-i)*(m-j)])%MOD);
        printf("%d\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值