m*n格填数方案

来源:互联网 发布:天眼软件下载 编辑:程序博客网 时间:2024/05/22 05:02

n*m格子每行和列至少填一格,求填格方案总数

关键词:容斥原理、模运算乘法溢出

Si设为i行不填数的方案,则:

根据容斥原理:


si和tj的交集元素个事容易计算,因此容易得到计算公式

#include<stdio.h>#include<iostream>#include<string.h>#include<algorithm>#include<map>#include<vector>#include<queue>#include<stack>#define ll long long#define sf scanf#define pf printf#define INF 0x3f3f3f3f#define mem(a,b) memset(a,b,sizeof(a))#define lowbit(x) x&(-x)const ll mol=1000000007;using namespace std;ll n,m;ll g[1000],c[100][100];ll C(ll m,ll n){    if(c[m][n]) return c[m][n]%mol;    if(n==0||m==n) return 1;    return c[m][n]=(C(m-1,n)%mol+C(m-1,n-1)%mol)%mol;}ll quick_pow(ll a,ll b){    ll ans=1;    while(b){        if(b&1) ans=(ans*a)%mol;        b/=2;        a=(a*a)%mol;    }    return (ans%mol);}int main(){    mem(c,0);    while(scanf("%lld%lld",&n,&m)!=EOF){        mem(g,0);        if(n==0||m==0) { printf("0\n"); continue; }        ll ans=quick_pow(2,m*n);        for(int i=0;i<=n;i++){//枚举i+j不如直接枚举i和j来的简便!!!            for(int j=0;j<=m;j++){                if(i+j>0){                    if((i+j)&1) ans=((ans-((C(n,i)*C(m,j))%mol*quick_pow(2,((n-i)*(m-j))%mol)))%mol+mol)%mol;                    else ans=((ans+((C(n,i)*C(m,j))%mol*quick_pow(2,((n-i)*(m-j)%mol)))%mol)%mol+mol)%mol;                }            }        }        printf("%lld\n",(ans+mol)%mol);    }}


0 0
原创粉丝点击