1493: 棋盘游戏(ac)

题目描述

在这里插入图片描述

题解

设实际反色行数为rr,则cc可以推出来
Nc+Mr2rc=SNc+Mr-2rc=S
所以我们可以枚举r,当遇到合法的r和c时,其对应方案是为
CNrCMcHNRr2HMCc2C_N^r*C_M^c*H_N^{\frac{R-r}{2}}*H_M^{\frac{C-c}{2}}
其中HnmH_n^m表示为从nn中可重复选出mm个元素
具体特判见代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const LL P=1e9+7,N=2e5+5;
LL n,m,r,c,s,jc[N],ny[N],a;
LL K(LL x,LL y){
    LL A=1;while(y){
        if (y&1) A=A*x%P;
        x=x*x%P;y>>=1;
    }return A;
}
LL C(LL x,LL y){
    if (x<y) return 0;
    return jc[x]*ny[y]%P*ny[x-y]%P;
}
int main(){
    jc[0]=1;for (LL i=1;i<N;i++) jc[i]=i*jc[i-1]%P;
    ny[N-1]=K(jc[N-1],P-2);for (LL i=N-1;i;i--) ny[i-1]=i*ny[i]%P;
    scanf("%lld%lld%lld%lld%lld",&n,&m,&r,&c,&s);
    for (LL i=0;i<=r;i++){
        if (n-2*i==0){
            if (s-m*i==0){
                LL x=r-i>>1ll;
                a=(a+C(n,i)*C(n+x-1,x)%P*C(m+c-1,c)%P)%P;
            }
            continue;
        }
        if ((s-m*i)%(n-2*i)) continue;
        LL j=(s-m*i)/(n-2*i);
        if (j>c || j<0 || ((r-i)&1ll) || ((c-j)&1ll)) continue;
        LL x=r-i>>1ll,y=c-j>>1ll;
        a=(a+C(n,i)*C(m,j)%P*C(n+x-1,x)%P*C(m+y-1,y)%P)%P;
    }
    return printf("%lld\n",a),0;
}
posted @ 2018-11-07 20:17  xjqxjq  阅读(158)  评论(0编辑  收藏  举报