题目大意
棋盘是一个无限大的二维平面,一开始马在原点 ( 0 , 0 ) (0,0) (0,0)上。马有两种移动方式:
- 从 ( u , v ) (u,v) (u,v)移动到 ( u + A x , v + A y ) (u+A_x,v+A_y) (u+Ax,v+Ay)。
- 从 ( u , v ) (u,v) (u,v)移动到 ( u + B x , v + B y ) (u+B_x,v+B_y) (u+Bx,v+By)。
平面上有 n n n个禁止点(坐标已给出),表示马不能走到这些点上。现在想知道马有多少种不同的移动方法到达点 ( E x , E y ) (E_x,E_y) (Ex,Ey)。答案模 1 0 9 + 7 10^9+7 109+7。
0
⩽
n
,
E
x
,
E
y
⩽
500
0\leqslant n,E_x,E_y\leqslant 500
0⩽n,Ex,Ey⩽500,所有数字的绝对值在
500
500
500以内。
数据保证
A
x
B
y
−
A
y
B
x
≠
0
A_xB_y-A_yB_x\neq0
AxBy−AyBx=0。
思路
由于棋盘是无限大的,直接递推的方法已经不再适用。
先考虑没有禁止点的情况。
把两种移动方式抽象成两个向量
a
⃗
=
(
A
x
,
A
y
)
\vec a=(A_x,A_y)
a=(Ax,Ay),
b
⃗
=
(
B
x
,
B
y
)
\vec b=(B_x,B_y)
b=(Bx,By)。假设马从点
P
P
P移动到点
Q
Q
Q,可以得到一个方程:
λ a ⃗ + μ b ⃗ = P Q → \lambda\vec a+\mu\vec b=\overrightarrow{PQ} λa+μb=PQ
题目保证 a ⃗ , b ⃗ \vec a,\vec b a,b不共线,根据平面向量基本定理, λ , μ \lambda,\mu λ,μ的值是唯一的。若两者均为非负整数,则马可以从点 P P P移动到点 Q Q Q,两种移动方式分别需要 λ \lambda λ次、 μ \mu μ次。显然在没有禁止点的情况下移动的顺序是不影响最终位置的,所以方案数为
K ( P , Q ) = ( λ + μ ) ! λ ! μ ! K(P,Q)=\frac{(\lambda+\mu)!}{\lambda!\mu!} K(P,Q)=λ!μ!(λ+μ)!
解读1: 总共有
λ
+
μ
\lambda+\mu
λ+μ次移动,假设所有移动各不相同,就有
(
λ
+
μ
)
!
(\lambda+\mu)!
(λ+μ)!中排列方式。其中有
λ
\lambda
λ次移动是相同的,这些移动的排列方式应该为
1
1
1,这里却算作不同,把排列方式算作了
λ
!
\lambda!
λ!,需要除掉。另外
μ
\mu
μ次移动同理。
解读2: 总共有
λ
+
μ
\lambda+\mu
λ+μ次移动,选出其中
λ
\lambda
λ次进行第一种移动方式,方案数就为
C
λ
+
μ
λ
C_{\lambda+\mu}^\lambda
Cλ+μλ。
然而这些移动方式中有一些经过了禁止点。设起点为
O
O
O,终点为
E
E
E,若
M
M
M是禁止点,则经过点
M
M
M的方案数就为
K
(
O
,
M
)
⋅
K
(
M
,
E
)
K(O,M)\cdot K(M,E)
K(O,M)⋅K(M,E),从总方案数中把所有经过禁止点的方案数减掉。
然而经过了两次禁止点的方案数被多减了一次,又把这些方案数加上……赤裸裸的容斥。
然而直接容斥的时间复杂度是
O
(
2
n
)
O(2^n)
O(2n)。受不了。
回到上面那个方程。当
P
Q
→
=
0
⃗
\overrightarrow{PQ}=\vec 0
PQ=0时,
λ
=
μ
=
0
\lambda=\mu=0
λ=μ=0,也就是说马在移动过程中不会回到之前已经经过的点。在容斥的过程中有
n
+
2
n+2
n+2个关键点:起点、终点、
n
n
n个禁止点。把这些点提出来,把从每个点出发能够到达的点与这个点用有向边相连,得到一张图,那么这张图一定是一个DAG,可以在上面DP。
定一个状态
f
[
u
]
[
i
]
f[u][i]
f[u][i]表示从起点走到
u
u
u号点,并且经过
i
i
i个禁止点的方案数。最终答案就为
f [ E ] [ 0 ] − f [ E ] [ 1 ] + f [ E ] [ 2 ] − f [ E ] [ 3 ] + ⋯ + ( − 1 ) n f [ E ] [ n ] f[E][0]-f[E][1]+f[E][2]-f[E][3]+\cdots+(-1)^nf[E][n] f[E][0]−f[E][1]+f[E][2]−f[E][3]+⋯+(−1)nf[E][n]
写出方程就会发现时间复杂度是 O ( n 3 ) O(n^3) O(n3)的。还是受不了。
由于容斥的时候 f [ u ] [ i ] f[u][i] f[u][i]的符号只与 i i i的奇偶性有关,不妨这样定状态: f [ u ] [ 1 ] f[u][1] f[u][1]表示从起点走到 u u u号点,并且经过奇数个禁止点的方案数, f [ u ] [ 0 ] f[u][0] f[u][0]表示从起点走到 u u u号点,并且经过偶数个禁止点的方案数。最终答案就为
f [ E ] [ 0 ] − f [ E ] [ 1 ] f[E][0]-f[E][1] f[E][0]−f[E][1]
答案很简洁,并且DP的时间复杂度是 O ( n 2 ) O(n^2) O(n2)。
补充
记录一下老板的标解。
前面的思路类似。在容斥掉经过禁止点的方案的时候,不必奇加偶减,只需枚举方案中经过的第一个禁止点:枚举一个禁止点
M
M
M,计算从起点到
M
M
M不经过其它禁止点的方案(从
M
M
M到终点可以经过其它禁止点),把这个方案减掉。这样,从起点到终点的每一个经过禁止点的方案只会在枚举到第一个禁止点的时候减掉。
状态为
f
[
i
]
f[i]
f[i],表示从起点走到
i
i
i号点,不经过其它禁止点的方案数。即用从起点到
i
i
i的所有方案数减去所有的
f
[
j
]
×
j
f[j]\times j
f[j]×j到
i
i
i的方案数,其中
j
j
j为
i
i
i的上一步可能的点。妥妥的
O
(
n
2
)
O(n^2)
O(n2)。