分配颜色
ADPC2-D
考点:排列组合
注释
- 只对行进行考虑考虑到对一行进行偶数此操作的效果相当于没操作,当一行操作奇数此操作的效果相当于操作一次,所以可以从大到小枚举有效操作的次数(注意如果可以操作的次数减去总的行数为奇数,应该从总行数-1开始考虑,枚举循环式应该每次减去2),列也如此考虑。总变化的方格数=im+jn-2ij,满足条件的可以进行排列组合
- 随后从总的行数里面选择有效行数,进行排列组合,得到组合数a。
- 再来考虑无效的操作次数,无效的操作次数/2得到,问题转化为将t个相同的物品,放进n个不同的盒子里(每个盒子可以放0个物品)的方案数,可以加上n个物品,转化为将t个相同的物品,放进n个不同的盒子里(每个盒子至少放1个物品),运用隔板法选择
- 将行得到的两个结果相乘并乘列的结果可以得到最终结果
- 注意:排列组合计算时不能运用逆元,因为模数不为质数,可以运用杨辉三角预处理出需要的值
#include<iostream>
#include<cstdio>
#define N 2000
#define ll long long
using namespace std;
const ll mod=555555555;
ll C[N][N];
ll initC(ll n)
{
for(int i=0;i<=n;i++)
{
for(int j=0;j<=i;j++)
{
if(i==0||j==0)C[i][j]=1;
else C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
//cout<<C[i][j]<<" ";
}
//cout<<endl;
}
}
int main()
{
//cout<<comb(999,999);
initC(1556);
ll n,m,q,p,t;
cin>>n>>m>>p>>q>>t;
ll Q,P;
if(n>p)
{
if((n-p)%2)P=n-1;
else P=n;
}
else P=p;
if(m>q)
{
if((m-q)%2)Q=m-1;
else Q=m;
}
else Q=q;
ll tot=0;
for(ll i=P;i>=0;i-=2)
{
for(ll j=Q;j>=0;j-=2)
{
if(i*m+j*n-2*i*j==t)
{
//cout<<i<<" "<<j<<endl;
ll x=(p-i)/2;
ll y=(q-j)/2;
tot=(tot+(C[n][i]*C[m][j])%mod*(C[n+x-1][n-1]*C[m+y-1][m-1])%mod)%mod;
}
}
}
cout<<tot;
return 0;
}