组合数模板:
#define ll long long
const ll mod = 555555555;
ll c[5000][5000];
void init(){
int i,j;
c[0][0]=1;
for(i=1;i<=4000;i++){
c[i][0]=1;c[i][i]=1;
for(j=1;j<i;j++){
c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
}
}
设被行变换的数量为a,列变化的数量为b,已进行的行变换为p,行操作为pcnt,列操作为qcnt.
那么1的个数就是
s
u
m
=
a
∗
m
+
b
∗
n
−
a
∗
b
sum =a*m+b*n-a*b
sum=a∗m+b∗n−a∗b.设i=p,j=q,那么a就是i一直减去2,j一直减去2,因为每次操作两次行或者两次列使其复原的代价为2,那么也就是
s
u
m
=
i
∗
m
+
j
∗
n
−
i
∗
j
∗
2
sum=i*m+j*n-i*j*2
sum=i∗m+j∗n−i∗j∗2.
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod = 555555555;
ll c[5000][5000];
void init(){
int i,j;
c[0][0]=1;
for(i=1;i<=4000;i++){
c[i][0]=1;c[i][i]=1;
for(j=1;j<i;j++){
c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
}
}
int main(){
init();
ll n,m,p,q,t;
scanf("%lld%lld%lld%lld%lld",&n,&m,&p,&q,&t);
ll ans=0;
for(ll i=p,pcnt=0;i>=0;i-=2,pcnt++){
if(i>n)continue;
ll sum=0;
for(ll j=q,qcnt=0;j>=0;j-=2,qcnt++){
if(j>m)continue;
sum=n*j+i*m-i*j*2;
if(sum==t)ans+=(((c[n][i]*c[pcnt+n-1][pcnt]))%mod)*((c[m][j]*c[qcnt+m-1][qcnt])%mod)%mod;
ans%=mod;
}
}
printf("%lld\n",ans);
}