码迷,mamicode.com
首页 > 其他好文 > 详细

HDU6314 Matrix

时间:2020-09-17 17:11:07      阅读:24      评论:0      收藏:0      [点我收藏+]

标签:wal   temp   答案   type   man   矩阵   protect   枚举   from   

HDU6314 Matrix

Problem 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.

思路:

容斥,先推式子

\[f(n,m)表示在大小为n*m的矩阵中每行、列均有白,\\容斥易得\f(n,m)=\sum_{i=0}^n\sum_{j=0}^m(-1)^{i+j}{n\choose i}{m\choose j}2^{(n-i)(m-j)} \F(n,m)表示矩阵大小为n*m的答案,\\显然枚举多少行、列全黑,去除全黑后剩下的矩阵每行、列不能全黑\\F(n,m)=\sum_{i=A}^{n}\sum_{j=B}^{m}{n\choose i}{m\choose j}f(n-i,m-j) \F(n,m)=\sum_{i=A}^{n}\sum_{j=B}^{m}{n\choose i}{m\choose j}\sum_{k=0}^{n-i}\sum_{l=0}^{m-j}(-1)^{k+l}{n-i\choose k}{m-j\choose l} 2^{(n-i-k)(m-j-l)} \F(n,m)=\sum_{i=A}^{n}\sum_{j=B}^{m}\left[{n\choose i}\sum_{k=0}^{n-i}(-1)^k{n-i\choose k}\right]\left[{m\choose j}\sum_{l=0}^{m-j}(-1)^l{m-j\choose l}\right]2^{(n-i-k)(m-j-l)}\枚举i、k得到第一部分的值,存下每个i+k对应的值g(i+k),\\同理可得每个j+l对应的值G(j+l),\\最后枚举i+k与j+l得到g(i+k)G(j+l)2^{(n-i-k)(m-j-l)}即为答案\时间复杂度为O(n^2+m^2+nm) \]

\(\mathfrak{Talk\ is\ cheap,show\ you\ the\ code.}\)

#include<map>
#include<cmath>
#include<stack>
#include<deque>
#include<queue>
#include<cstdio>
#include<vector>
#include<climits>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
# define Type template<typename T>
# define ll long long
# define read read1<ll>()
Type T read1(){
    T t=0;char k;
    bool v=0;
    do (k=getchar())==‘-‘&&(v=1);while(‘0‘>k||k>‘9‘);
    while(‘0‘<=k&&k<=‘9‘)t=(t<<3)+(t<<1)+(k^‘0‘),k=getchar();
    return v?-t:t;
}
ll qkpow(ll n,ll x,ll mo){
    if(!x)return 1;
    ll t=qkpow(n,x>>1,mo);
    t=t*t%mo;
    if(x&1)t=t*n%mo;
    return t;
}
# define mod 998244353ll
# define I 499122177ll
# define N 3000
ll fac[N|3],inv[N|3];
ll Ch(ll m,ll n){
    if(m<n)return 0;
    return fac[m]*inv[m-n]%mod*inv[n]%mod;
}
void init(){
    fac[0]=1;
    for(int i=1;i<=N;++i)
        fac[i]=fac[i-1]*i%mod;
    inv[N]=qkpow(fac[N],mod-2,mod);
    for(int i=N;i;--i)
        inv[i-1]=inv[i]*i%mod;
}
ll invi(ll x){return qkpow(x,mod-2,mod);}
ll f[6005],f1[6005];
int main(){
    init();
    int n,m,A,B;
    while(~scanf("%d %d %d %d",&n,&m,&A,&B)){
        ll ans=0;
        memset(f,0,sizeof(f));
        memset(f1,0,sizeof(f1));
        for(int i=A;i<=n;++i)
            for(int k=0;k<=n-i;++k)
                f[i+k]=(f[i+k]+1ll*(k&1?-1:1)*Ch(n-i,k)*Ch(n,i))%mod;
        for(int i=B;i<=m;++i)
            for(int k=0;k<=m-i;++k)
                f1[i+k]=(f1[i+k]+1ll*(k&1?-1:1)*Ch(m-i,k)*Ch(m,i))%mod;
        for(int i=A;i<=n;++i)
            for(int j=B,v=qkpow(2,(n-i)*(m-j),mod),x=invi(qkpow(2,n-i,mod));j<=m;v=1ll*x*v%mod,++j)
                ans=(ans+f[i]*f1[j]%mod*v)%mod;
        printf("%lld\n",(ans+mod)%mod);
    }
    return 0;
}  

HDU6314 Matrix

标签:wal   temp   答案   type   man   矩阵   protect   枚举   from   

原文地址:https://www.cnblogs.com/SYDevil/p/13626097.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!