题意:走
N
N
N步从
(
0
,
0
,
0
)
(0,0,0)
(0,0,0)走到
(
X
,
Y
,
Z
)
(X,Y,Z)
(X,Y,Z)的不同路径条数(每一步不能不走且步长为1)
不失一般性的我们可以设
(
X
,
Y
,
Z
>
0
)
(X,Y,Z>0)
(X,Y,Z>0)
首先考虑走
(
X
+
Y
+
2
k
)
(X+Y+2k)
(X+Y+2k)步从
(
0
,
0
)
(0,0)
(0,0)走到
(
X
,
Y
)
(X,Y)
(X,Y)
枚举
X
X
X正方向的步数
(
X
+
i
)
(X+i)
(X+i),总的走法就是
C
x
+
y
+
2
k
k
∑
i
=
0
k
C
k
i
×
C
x
+
y
+
k
x
+
i
=
C
x
+
y
+
2
k
k
∑
i
=
0
k
C
k
k
−
i
×
C
x
+
y
+
k
x
+
i
=
C
x
+
y
+
2
k
k
×
C
x
+
y
+
2
k
y
+
k
C^k_{x+y+2k}\sum _{i=0}^{k}C_k^i\times C_{x+y+k}^{x+i}=C^k_{x+y+2k}\sum _{i=0}^{k}C_k^{k-i}\times C_{x+y+k}^{x+i}=C^k_{x+y+2k} \times C_{x+y+2k}^{y+k}
Cx+y+2kki=0∑kCki×Cx+y+kx+i=Cx+y+2kki=0∑kCkk−i×Cx+y+kx+i=Cx+y+2kk×Cx+y+2ky+k
其中
C
x
+
y
+
2
k
k
C^k_{x+y+2k}
Cx+y+2kk枚举了多走的
k
k
k步的位置,
C
k
i
×
C
x
+
y
+
k
x
+
i
C_k^i\times C_{x+y+k}^{x+i}
Cki×Cx+y+kx+i分别枚举了
X
X
X方向回退的
i
i
i步的位置和
X
X
X方向走的
(
X
+
i
)
(X+i)
(X+i)步位置
其中等式
∑
i
=
0
k
C
k
k
−
i
×
C
x
+
y
+
k
x
+
i
=
C
x
+
y
+
2
k
y
+
k
\sum _{i=0}^{k}C_k^{k-i}\times C_{x+y+k}^{x+i}=C_{x+y+2k}^{y+k}
∑i=0kCkk−i×Cx+y+kx+i=Cx+y+2ky+k是著名的范德蒙恒等式
一般形式为
∑
i
=
0
k
C
m
k
−
i
×
C
n
i
=
C
m
+
n
k
\sum _{i=0}^{k}C_{m}^{k-i}\times C^i_{n}=C^k_{m+n}
∑i=0kCmk−i×Cni=Cm+nk
推导过程如下:
考虑在一堆和为 ( m + n ) (m+n) (m+n)数量的物品中选 k k k个的方案数,考虑前 n n n个中选了 i i i个,后 m m m个中选了 ( k − i ) (k-i) (k−i)个的方案,枚举所有 i i i求和就得到了答案。
接下来考虑
Z
Z
Z方向上的情况,剩余未考虑的步数为
N
−
(
X
+
Y
+
2
k
)
N-(X+Y+2k)
N−(X+Y+2k),这些步数中朝
Z
Z
Z负方向的有
(
N
−
(
X
+
Y
+
Z
+
2
k
)
)
/
2
(N-(X+Y+Z+2k))/2
(N−(X+Y+Z+2k))/2步,其余为正方向
则对于某个
k
k
k,方案为
C
x
+
y
+
2
k
k
×
C
x
+
y
+
2
k
y
+
k
×
C
N
N
−
(
x
+
y
+
2
k
)
×
C
N
−
(
X
+
Y
+
2
k
)
(
N
−
(
X
+
Y
+
Z
+
2
k
)
)
/
2
C^k_{x+y+2k} \times C_{x+y+2k}^{y+k}\times C^{N-(x+y+2k)}_{N}\times C^{(N-(X+Y+Z+2k))/2}_{N-(X+Y+2k)}
Cx+y+2kk×Cx+y+2ky+k×CNN−(x+y+2k)×CN−(X+Y+2k)(N−(X+Y+Z+2k))/2
枚举所有
k
k
k就得到了答案,复杂度
O
(
N
)
O(N)
O(N)
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=998244353;
ll poww(ll a,ll b)
{
ll t=1;
while(b)
{
if(b&1)t=a*t%mod;
a=a*a%mod;
b>>=1;
}
return t;
}
ll inv(ll x)
{
return poww(x,mod-2);
}
ll P1[10000005],P2[10000005];
void init()
{
P1[0]=1;
for(int i=1;i<=10000000;i++)P1[i]=1LL*P1[i-1]*i%mod;
P2[10000000]=inv(P1[10000000]);
for(int i=9999999;i>=0;i--)P2[i]=1LL*P2[i+1]*(i+1)%mod;
}
ll C(ll n,ll m)
{
return 1LL*P1[n]*P2[m]%mod*P2[n-m]%mod;
}
int main()
{
init();
ll N,X,Y,Z;
scanf("%lld%lld%lld%lld",&N,&X,&Y,&Z);
X=abs(X);
Y=abs(Y);
Z=abs(Z);
ll left=N-X-Y-Z;
if(left<0||(left%2!=0))printf("0");
else
{
ll ans=0;
for(int k=0;k<=left/2;k++)
{
ans=(ans+1LL*C(X+Y+2*k,k)*
C(X+Y+2*k,Y+k)%mod*
C(N,N-(X+Y+2*k))%mod*
C(N-(X+Y+2*k),(N-(X+Y+2*k+Z))/2)%mod
)%mod;
}
printf("%lld\n",ans);
}
return 0;
}