Description:
题解:
很容易想到如果不计一开始一列的相对顺序。
就可以重写每一列状态为0、1、2表示没有R,G,B的。
接着枚举第一列是哪个,再枚举有几个空,接着枚举奇数的空的个数,接着列方程求出奇数中有几个是谁开头的,然后组合数一波流。
Code:
#include<cstdio>
#include<algorithm>
#define ll long long
#define fo(i, x, y) for(int i = x; i <= y; i ++)
#define fd(i, x, y) for(int i = x; i >= y; i --)
using namespace std;
const int mo = 1e9 + 7;
int n, a[3];
const int N = 2e6;
ll ksm(ll x, ll y) {
ll s = 1;
for(; y; y /= 2, x = x * x % mo)
if(y & 1) s = s * x % mo;
return s;
}
ll fac[N + 1], nf[N + 1], ans;
ll C(ll n, ll m) {
if(n < m || n < 0 || m < 0) return 0;
return fac[n] * nf[n - m] % mo * nf[m] % mo;
}
int main() {
fac[0] = 1; fo(i, 1, N) fac[i] = fac[i - 1] * i % mo;
nf[N] = ksm(fac[N], mo - 2); fd(i, N - 1, 0) nf[i] = nf[i + 1] * (i + 1) % mo;
scanf("%d", &n);
fo(i, 0, 2) scanf("%d", &a[i]), a[i] = n - a[i];
fo(i, 0, 2) {
fo(ii, 0, 1) {
int g = a[i] - ii;
if(g <= 0) continue;
int y, z;
if(i == 0) y = a[1], z = a[2];
if(i == 1) y = a[0], z = a[2];
if(i == 2) y = a[0], z = a[1];
fo(e, 0, g) {
if((y - z + g - e) & 1) continue;
int oy = (y - z + g - e) / 2, oz = g - e - oy;
int r = y - e - oy;
ans = (ans + C(g + r - 1, r) * C(g, e) % mo * C(g - e, oy) % mo * ksm(2, e) % mo) % mo;
}
}
}
printf("%lld", ans * 2 % mo);
}