2021牛客暑期多校训练营9
Cells(LGV引理,FFT)
题意
在一个无限大的 x y xy xy坐标轴上,求从 A = { ( 0 , a 1 ) , ( 0 , a 2 ) , . . . , ( 0 , a n ) } A=\{(0,a_1),(0,a_2),...,(0,a_n)\} A={(0,a1),(0,a2),...,(0,an)}分别到 B = { ( 1 , 0 ) , ( 2 , 0 ) , . . . , ( n , 0 ) } B=\{(1,0),(2,0),...,(n,0)\} B={(1,0),(2,0),...,(n,0)},不相交路径的方案数。
并且对于每个点 A i ( x , y ) A_i(x,y) Ai(x,y)每一步只能移动到 ( x + 1 , y ) o r ( x , y − 1 ) (x+1,y)\ or\ (x,y-1) (x+1,y) or (x,y−1)。
思路
因为每一个格子只能向两个方向移动,并且路径不会存在环,则可以将表格视为一个有向无环图。
考虑使用LGV引理,则答案为:
M
=
[
e
(
A
1
,
B
1
)
e
(
A
1
,
B
2
)
⋯
e
(
A
1
,
B
n
)
e
(
A
2
,
B
1
)
e
(
A
2
,
B
2
)
⋯
e
(
A
2
,
B
n
)
⋮
⋮
⋱
⋮
e
(
A
n
,
B
1
)
e
(
A
n
,
B
2
)
⋯
e
(
A
n
,
B
n
)
]
M= \begin{bmatrix} e(A_1,B_1) & e(A_1,B_2) & \cdots & e(A_1,B_n) \\ e(A_2,B_1) & e(A_2,B_2) & \cdots & e(A_2,B_n) \\ \vdots & \vdots & \ddots & \vdots \\ e(A_n,B_1) & e(A_n,B_2) & \cdots & e(A_n,B_n) \\ \end{bmatrix}
M=⎣⎢⎢⎢⎡e(A1,B1)e(A2,B1)⋮e(An,B1)e(A1,B2)e(A2,B2)⋮e(An,B2)⋯⋯⋱⋯e(A1,Bn)e(A2,Bn)⋮e(An,Bn)⎦⎥⎥⎥⎤
M
i
,
j
=
e
(
A
i
,
B
j
)
M_{i,j}=e(A_i,B_j)
Mi,j=e(Ai,Bj),当所有边权都设为
1
1
1时,
∀
P
,
w
(
P
)
=
1
\forall P,w(P)=1
∀P,w(P)=1,则
e
(
A
i
,
B
j
)
e(A_i,B_j)
e(Ai,Bj)等价于求
A
i
A_i
Ai到
B
j
B_j
Bj的路径数。(最好先去看看LGV引理的结论)
考虑如何求 A i ( 0 , a i ) A_i(0,a_i) Ai(0,ai)到 B j ( j , 0 ) B_j(j,0) Bj(j,0)的方案数:
A
i
A_i
Ai到
B
j
B_j
Bj无论怎么走,都必须向右走
j
j
j步和向下走
a
i
a_i
ai步,可以使用排列组合,排列哪一步是向右走的,
C
j
+
a
i
j
C_{j+a_i}^{j}
Cj+aij。
C
j
+
a
i
j
=
(
j
+
a
i
)
!
j
!
×
(
j
+
a
i
−
j
)
!
=
(
j
+
a
i
)
!
j
!
×
a
i
!
C_{j+a_i}^{j}=\frac{(j+a_i)!}{j!\times (j+a_i-j)!}=\frac{(j+a_i)!}{j!\times a_i!}
Cj+aij=j!×(j+ai−j)!(j+ai)!=j!×ai!(j+ai)!
将上面排列组合得到的式子代入
M
M
M,然后进行化简:
M
=
[
(
1
+
a
1
)
!
1
!
×
a
1
!
(
2
+
a
1
)
!
2
!
×
a
1
!
⋯
(
n
+
a
1
)
!
n
!
×
a
1
!
(
1
+
a
2
)
!
1
!
×
a
2
!
(
2
+
a
2
)
!
2
!
×
a
2
!
⋯
(
n
+
a
2
)
!
n
!
×
a
2
!
⋮
⋮
⋱
⋮
(
1
+
a
n
)
!
1
!
×
a
n
!
(
2
+
a
n
)
!
2
!
×
a
n
!
⋯
(
n
+
a
n
)
!
n
!
×
a
n
!
]
①
=
∏
j
=
1
n
1
j
!
×
[
(
1
+
a
1
)
!
a
1
!
(
2
+
a
1
)
!
a
1
!
⋯
(
n
+
a
1
)
!
a
1
!
(
1
+
a
2
)
!
a
2
!
(
2
+
a
2
)
!
a
2
!
⋯
(
n
+
a
2
)
!
a
2
!
⋮
⋮
⋱
⋮
(
1
+
a
n
)
!
a
n
!
(
2
+
a
n
)
!
a
n
!
⋯
(
n
+
a
n
)
!
a
n
!
]
②
=
∏
j
=
1
n
1
j
!
×
[
(
1
+
a
1
)
(
1
+
a
1
)
(
2
+
a
1
)
⋯
(
1
+
a
1
)
(
2
+
a
1
)
.
.
.
(
n
+
a
1
)
(
1
+
a
2
)
(
1
+
a
2
)
(
2
+
a
2
)
⋯
(
1
+
a
2
)
(
2
+
a
2
)
.
.
.
(
n
+
a
2
)
⋮
⋮
⋱
⋮
(
1
+
a
n
)
(
1
+
a
n
)
(
2
+
a
n
)
⋯
(
1
+
a
1
)
(
2
+
a
n
)
.
.
.
(
n
+
a
n
)
]
③
=
∏
j
=
1
n
1
j
!
×
[
(
1
+
a
1
)
(
1
+
a
1
)
2
⋯
(
1
+
a
1
)
n
(
1
+
a
2
)
(
1
+
a
2
)
2
⋯
(
1
+
a
2
)
n
⋮
⋮
⋱
⋮
(
1
+
a
n
)
(
1
+
a
n
)
2
⋯
(
1
+
a
n
)
n
]
④
=
∏
j
=
1
n
1
j
!
×
∏
k
=
1
n
(
1
+
a
k
)
×
[
1
(
1
+
a
1
)
⋯
(
1
+
a
1
)
(
n
−
1
)
1
(
1
+
a
2
)
⋯
(
1
+
a
2
)
(
n
−
1
)
⋮
⋮
⋱
⋮
1
(
1
+
a
n
)
⋯
(
1
+
a
n
)
(
n
−
1
)
]
⑥
=
∏
j
=
1
n
1
j
!
×
∏
k
=
1
n
(
1
+
a
k
)
×
∏
1
≤
i
′
<
j
′
≤
n
−
1
(
(
a
i
′
+
1
)
−
(
a
j
′
+
1
)
)
⑤
=
∏
j
=
1
n
1
j
!
×
∏
k
=
1
n
(
1
+
a
k
)
×
∏
1
≤
i
′
<
j
′
≤
n
(
a
i
′
−
a
j
′
)
⑦
\begin{matrix} M &=& \begin{bmatrix} \frac{(1+a_1)!}{1!\times a_1!} & \frac{(2+a_1)!}{2!\times a_1!} & \cdots & \frac{(n+a_1)!}{n!\times a_1!} \\ \frac{(1+a_2)!}{1!\times a_2!} & \frac{(2+a_2)!}{2!\times a_2!} & \cdots & \frac{(n+a_2)!}{n!\times a_2!} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{(1+a_n)!}{1!\times a_n!} & \frac{(2+a_n)!}{2!\times a_n!} & \cdots & \frac{(n+a_n)!}{n!\times a_n!} \\ \end{bmatrix} &①& \\ &=& \prod_{j=1}^{n}\frac{1}{j!}\times \begin{bmatrix} \frac{(1+a_1)!}{a_1!} & \frac{(2+a_1)!}{a_1!} & \cdots & \frac{(n+a_1)!}{a_1!} \\ \frac{(1+a_2)!}{a_2!} & \frac{(2+a_2)!}{a_2!} & \cdots & \frac{(n+a_2)!}{a_2!} \\ \vdots & \vdots & \ddots & \vdots \\ \frac{(1+a_n)!}{a_n!} & \frac{(2+a_n)!}{a_n!} & \cdots & \frac{(n+a_n)!}{a_n!} \\ \end{bmatrix} &②& \\ &=& \prod_{j=1}^{n}\frac{1}{j!}\times \begin{bmatrix} (1+a_1) & (1+a_1)(2+a_1) & \cdots & (1+a_1)(2+a_1)...(n+a_1) \\ (1+a_2) & (1+a_2)(2+a_2) & \cdots & (1+a_2)(2+a_2)...(n+a_2) \\ \vdots & \vdots & \ddots & \vdots \\ (1+a_n) & (1+a_n)(2+a_n) & \cdots & (1+a_1)(2+a_n)...(n+a_n) \\ \end{bmatrix} &③& \\ &=& \prod_{j=1}^{n}\frac{1}{j!}\times \begin{bmatrix} (1+a_1) & (1+a_1)^2 & \cdots & (1+a_1)^n \\ (1+a_2) & (1+a_2)^2 & \cdots & (1+a_2)^n \\ \vdots & \vdots & \ddots & \vdots \\ (1+a_n) & (1+a_n)^2 & \cdots & (1+a_n)^n \\ \end{bmatrix} &④& \\ &=& \prod_{j=1}^{n}\frac{1}{j!} \times \prod_{k=1}^{n}(1+a_k) \times \begin{bmatrix} 1 & (1+a_1) & \cdots & (1+a_1)^(n-1) \\ 1 & (1+a_2) & \cdots & (1+a_2)^(n-1) \\ \vdots & \vdots & \ddots & \vdots \\ 1 & (1+a_n) & \cdots & (1+a_n)^(n-1) \\ \end{bmatrix} &⑥& \\ &=& \prod_{j=1}^{n}\frac{1}{j!} \times \prod_{k=1}^{n}(1+a_k) \times \prod_{1\le i'<j' \le n-1}((a_{i'}+1)-(a_{j'}+1)) &⑤& \\ &=& \prod_{j=1}^{n}\frac{1}{j!} \times \prod_{k=1}^{n}(1+a_k) \times \prod_{1\le i'<j' \le n}(a_{i'}-a_{j'}) &⑦& \end{matrix}
M=======⎣⎢⎢⎢⎢⎡1!×a1!(1+a1)!1!×a2!(1+a2)!⋮1!×an!(1+an)!2!×a1!(2+a1)!2!×a2!(2+a2)!⋮2!×an!(2+an)!⋯⋯⋱⋯n!×a1!(n+a1)!n!×a2!(n+a2)!⋮n!×an!(n+an)!⎦⎥⎥⎥⎥⎤∏j=1nj!1×⎣⎢⎢⎢⎢⎡a1!(1+a1)!a2!(1+a2)!⋮an!(1+an)!a1!(2+a1)!a2!(2+a2)!⋮an!(2+an)!⋯⋯⋱⋯a1!(n+a1)!a2!(n+a2)!⋮an!(n+an)!⎦⎥⎥⎥⎥⎤∏j=1nj!1×⎣⎢⎢⎢⎡(1+a1)(1+a2)⋮(1+an)(1+a1)(2+a1)(1+a2)(2+a2)⋮(1+an)(2+an)⋯⋯⋱⋯(1+a1)(2+a1)...(n+a1)(1+a2)(2+a2)...(n+a2)⋮(1+a1)(2+an)...(n+an)⎦⎥⎥⎥⎤∏j=1nj!1×⎣⎢⎢⎢⎡(1+a1)(1+a2)⋮(1+an)(1+a1)2(1+a2)2⋮(1+an)2⋯⋯⋱⋯(1+a1)n(1+a2)n⋮(1+an)n⎦⎥⎥⎥⎤∏j=1nj!1×∏k=1n(1+ak)×⎣⎢⎢⎢⎡11⋮1(1+a1)(1+a2)⋮(1+an)⋯⋯⋱⋯(1+a1)(n−1)(1+a2)(n−1)⋮(1+an)(n−1)⎦⎥⎥⎥⎤∏j=1nj!1×∏k=1n(1+ak)×∏1≤i′<j′≤n−1((ai′+1)−(aj′+1))∏j=1nj!1×∏k=1n(1+ak)×∏1≤i′<j′≤n(ai′−aj′)①②③④⑥⑤⑦
对矩阵化简的操作进行解释:
-
第②步操作是根据行列式的性质,将每一列的 j ! j! j!都提到前面。
行列式中的某一行(列)的所有元素的公因子都可以提到行列式记号的外边。
[ b 1 × a 1 , 1 b 1 × a 1 , 2 ⋯ b 1 × a 1 , n b 2 × a 2 , 1 b 2 × a 2 , 2 ⋯ b 2 × a 2 , n ⋮ ⋮ ⋱ ⋮ b n × a n , 1 b n × a n , 2 ⋯ b n × a n , n ] = ∏ j = 1 n b j × [ a 1 , 1 a 1 , 2 ⋯ a 1 , n a 2 , 1 a 2 , 2 ⋯ a 2 , n ⋮ ⋮ ⋱ ⋮ a n , 1 a n , 2 ⋯ a n , n ] \begin{bmatrix} b_1\times a_{1,1} & b_1\times a_{1,2} & \cdots & b_1\times a_{1,n} \\ b_2\times a_{2,1} & b_2\times a_{2,2} & \cdots & b_2\times a_{2,n} \\ \vdots & \vdots & \ddots & \vdots \\ b_n\times a_{n,1} & b_n\times a_{n,2} & \cdots & b_n\times a_{n,n} \\ \end{bmatrix} = \prod_{j=1}^{n}b_j \times \begin{bmatrix} a_{1,1} & a_{1,2} & \cdots & a_{1,n} \\ a_{2,1} & a_{2,2} & \cdots & a_{2,n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{n,1} & a_{n,2} & \cdots & a_{n,n} \\ \end{bmatrix} ⎣⎢⎢⎢⎡b1×a1,1b2×a2,1⋮bn×an,1b1×a1,2b2×a2,2⋮bn×an,2⋯⋯⋱⋯b1×a1,nb2×a2,n⋮bn×an,n⎦⎥⎥⎥⎤=j=1∏nbj×⎣⎢⎢⎢⎡a1,1a2,1⋮an,1a1,2a2,2⋮an,2⋯⋯⋱⋯a1,na2,n⋮an,n⎦⎥⎥⎥⎤
-
对第④步操作是根据行列式的性质。
将行列式的某一行(列)的各元素乘以同一个数k后加到另一行(列)对应的元素上,行列式的值不变。
举一个三阶的例子:
M ′ = [ ( 1 + a 1 ) ( 1 + a 1 ) ( 2 + a 1 ) ( 1 + a 1 ) ( 2 + a 1 ) ( 3 + a 1 ) ( 1 + a 2 ) ( 1 + a 2 ) ( 2 + a 2 ) ( 1 + a 2 ) ( 2 + a 2 ) ( 3 + a 2 ) ( 1 + a 3 ) ( 1 + a 3 ) ( 2 + a 3 ) ( 1 + a 3 ) ( 2 + a 3 ) ( 3 + a 3 ) ] = [ ( 1 + a 1 ) ( 1 + a 1 ) ( 2 + a 1 ) ( 1 + a 1 ) ( 2 + a 1 ) ( 3 + a 1 ) − ( 1 + a 1 ) ( 2 + a 1 ) × 2 ( 1 + a 2 ) ( 1 + a 2 ) ( 2 + a 2 ) ( 1 + a 2 ) ( 2 + a 2 ) ( 3 + a 2 ) − ( 1 + a 2 ) ( 2 + a 2 ) × 2 ( 1 + a 3 ) ( 1 + a 3 ) ( 2 + a 3 ) ( 1 + a 3 ) ( 2 + a 3 ) ( 3 + a 3 ) − ( 1 + a 3 ) ( 2 + a 3 ) × 2 ] = [ ( 1 + a 1 ) ( 1 + a 1 ) ( 2 + a 1 ) ( 1 + a 1 ) 2 ( 2 + a 1 ) ( 1 + a 2 ) ( 1 + a 2 ) ( 2 + a 2 ) ( 1 + a 2 ) 2 ( 2 + a 2 ) ( 1 + a 3 ) ( 1 + a 3 ) ( 2 + a 3 ) ( 1 + a 3 ) 2 ( 2 + a 3 ) ] = [ ( 1 + a 1 ) ( 1 + a 1 ) ( 2 + a 1 ) − ( 1 + a 1 ) ( 1 + a 1 ) 2 ( 2 + a 1 ) ( 1 + a 2 ) ( 1 + a 2 ) ( 2 + a 2 ) − ( 1 + a 2 ) ( 1 + a 2 ) 2 ( 2 + a 2 ) ( 1 + a 3 ) ( 1 + a 3 ) ( 2 + a 3 ) − ( 1 + a 3 ) ( 1 + a 3 ) 2 ( 2 + a 3 ) ] = [ ( 1 + a 1 ) ( 1 + a 1 ) 2 ( 1 + a 1 ) 2 ( 2 + a 1 ) ( 1 + a 2 ) ( 1 + a 2 ) 2 ( 1 + a 2 ) 2 ( 2 + a 2 ) ( 1 + a 3 ) ( 1 + a 3 ) 2 ( 1 + a 3 ) 2 ( 2 + a 3 ) ] = [ ( 1 + a 1 ) ( 1 + a 1 ) 2 ( 1 + a 1 ) 2 ( 2 + a 1 ) − ( 1 + a 1 ) 2 ( 1 + a 2 ) ( 1 + a 2 ) 2 ( 1 + a 2 ) 2 ( 2 + a 2 ) − ( 1 + a 2 ) 2 ( 1 + a 3 ) ( 1 + a 3 ) 2 ( 1 + a 3 ) 2 ( 2 + a 3 ) − ( 1 + a 3 ) 2 ] = [ ( 1 + a 1 ) ( 1 + a 1 ) 2 ( 1 + a 1 ) 3 ( 1 + a 2 ) ( 1 + a 2 ) 2 ( 1 + a 2 ) 3 ( 1 + a 3 ) ( 1 + a 3 ) 2 ( 1 + a 3 ) 3 ] \begin{matrix} M' &=& \begin{bmatrix} (1+a_1) & (1+a_1)(2+a_1) & (1+a_1)(2+a_1)(3+a_1) \\ (1+a_2) & (1+a_2)(2+a_2) & (1+a_2)(2+a_2)(3+a_2) \\ (1+a_3) & (1+a_3)(2+a_3) & (1+a_3)(2+a_3)(3+a_3) \\ \end{bmatrix} \\ &=& \begin{bmatrix} (1+a_1) & (1+a_1)(2+a_1) & (1+a_1)(2+a_1)(3+a_1)- (1+a_1)(2+a_1)\times 2\\ (1+a_2) & (1+a_2)(2+a_2) & (1+a_2)(2+a_2)(3+a_2)- (1+a_2)(2+a_2)\times 2 \\ (1+a_3) & (1+a_3)(2+a_3) & (1+a_3)(2+a_3)(3+a_3)- (1+a_3)(2+a_3)\times 2 \\ \end{bmatrix} \\ &=& \begin{bmatrix} (1+a_1) & (1+a_1)(2+a_1) & (1+a_1)^2(2+a_1) \\ (1+a_2) & (1+a_2)(2+a_2) & (1+a_2)^2(2+a_2) \\ (1+a_3) & (1+a_3)(2+a_3) & (1+a_3)^2(2+a_3) \\ \end{bmatrix} \\ &=& \begin{bmatrix} (1+a_1) & (1+a_1)(2+a_1)-(1+a_1) & (1+a_1)^2(2+a_1) \\ (1+a_2) & (1+a_2)(2+a_2)-(1+a_2) & (1+a_2)^2(2+a_2) \\ (1+a_3) & (1+a_3)(2+a_3)-(1+a_3) & (1+a_3)^2(2+a_3) \\ \end{bmatrix} \\ &=& \begin{bmatrix} (1+a_1) & (1+a_1)^2 & (1+a_1)^2(2+a_1) \\ (1+a_2) & (1+a_2)^2 & (1+a_2)^2(2+a_2) \\ (1+a_3) & (1+a_3)^2 & (1+a_3)^2(2+a_3) \\ \end{bmatrix} \\ &=& \begin{bmatrix} (1+a_1) & (1+a_1)^2 & (1+a_1)^2(2+a_1)-(1+a_1)^2 \\ (1+a_2) & (1+a_2)^2 & (1+a_2)^2(2+a_2)-(1+a_2)^2 \\ (1+a_3) & (1+a_3)^2 & (1+a_3)^2(2+a_3)-(1+a_3)^2 \\ \end{bmatrix} \\ &=& \begin{bmatrix} (1+a_1) & (1+a_1)^2 & (1+a_1)^3 \\ (1+a_2) & (1+a_2)^2 & (1+a_2)^3 \\ (1+a_3) & (1+a_3)^2 & (1+a_3)^3 \\ \end{bmatrix} \end{matrix} M′=======⎣⎡(1+a1)(1+a2)(1+a3)(1+a1)(2+a1)(1+a2)(2+a2)(1+a3)(2+a3)(1+a1)(2+a1)(3+a1)(1+a2)(2+a2)(3+a2)(1+a3)(2+a3)(3+a3)⎦⎤⎣⎡(1+a1)(1+a2)(1+a3)(1+a1)(2+a1)(1+a2)(2+a2)(1+a3)(2+a3)(1+a1)(2+a1)(3+a1)−(1+a1)(2+a1)×2(1+a2)(2+a2)(3+a2)−(1+a2)(2+a2)×2(1+a3)(2+a3)(3+a3)−(1+a3)(2+a3)×2⎦⎤⎣⎡(1+a1)(1+a2)(1+a3)(1+a1)(2+a1)(1+a2)(2+a2)(1+a3)(2+a3)(1+a1)2(2+a1)(1+a2)2(2+a2)(1+a3)2(2+a3)⎦⎤⎣⎡(1+a1)(1+a2)(1+a3)(1+a1)(2+a1)−(1+a1)(1+a2)(2+a2)−(1+a2)(1+a3)(2+a3)−(1+a3)(1+a1)2(2+a1)(1+a2)2(2+a2)(1+a3)2(2+a3)⎦⎤⎣⎡(1+a1)(1+a2)(1+a3)(1+a1)2(1+a2)2(1+a3)2(1+a1)2(2+a1)(1+a2)2(2+a2)(1+a3)2(2+a3)⎦⎤⎣⎡(1+a1)(1+a2)(1+a3)(1+a1)2(1+a2)2(1+a3)2(1+a1)2(2+a1)−(1+a1)2(1+a2)2(2+a2)−(1+a2)2(1+a3)2(2+a3)−(1+a3)2⎦⎤⎣⎡(1+a1)(1+a2)(1+a3)(1+a1)2(1+a2)2(1+a3)2(1+a1)3(1+a2)3(1+a3)3⎦⎤ -
对第⑤步操作是根据范德蒙行列式的性质。
最后的结果就是求 M = ∏ j = 1 n j ! × ∏ k = 1 n ( 1 + a k ) × ∏ 1 ≤ i ′ < j ′ ≤ n ( a i ′ − a j ′ ) M=\prod_{j=1}^{n}j! \times \prod_{k=1}^{n}(1+a_k) \times \prod_{1\le i'<j' \le n}(a_{i'}-a_{j'}) M=∏j=1nj!×∏k=1n(1+ak)×∏1≤i′<j′≤n(ai′−aj′)。
后边这个很明显是一个卷积,可以用FFT来做,和牛客第一场的Hash Function很像,可以先看下这个题解。
AC的代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const double PI = acos(-1);
const int P = 1e6+10;
const int N = 5e6+100, mod = 998244353;
int limit, bit;
ll R[N];
// 复数的板子
struct Complex {
double x, y;
Complex(double x = 0, double y = 0) : x(x), y(y) { }
} a[N], b[N];
Complex operator * (Complex J, Complex Q) {
return Complex(J.x * Q.x - J.y * Q.y, J.x * Q.y + J.y * Q.x);
}
Complex operator - (Complex J, Complex Q) {
return Complex(J.x - Q.x, J.y - Q.y);
}
Complex operator + (Complex J, Complex Q) {
return Complex(J.x + Q.x, J.y + Q.y);
}
//FFT板子
void FFT(Complex * A, int type) {
for (int i = 0; i < limit; ++i)
if (i < R[i])
swap(A[i], A[R[i]]);
for (int mid = 1; mid < limit; mid <<= 1) {
Complex wn(cos(PI / mid), type * sin(PI / mid));
for (int len = mid << 1, pos = 0; pos < limit; pos += len) {
Complex w(1, 0);
for (int k = 0; k < mid; ++k, w = w * wn) {
Complex x = A[pos + k];
Complex y = w * A[pos + mid + k];
A[pos + k] = x + y;
A[pos + mid + k] = x - y;
}
}
}
if (type == 1) return;
for (int i = 0; i <= limit; ++i)
a[i].x /= limit, a[i].y /= limit;
}
ll power(ll a, ll b){
ll res = 1;
while(b){
if(b & 1) res = (res * a) % mod;
b >>= 1;
a = (a * a) % mod;
}
return res;
}
ll inv(ll a){
return power(a, mod-2);
}
int main() {
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin.exceptions(ios::badbit | ios::failbit);
//freopen("input.txt", "r", stdin);
int n;
cin>>n;
ll res = 1;
ll fac = 1;
for(int i = 1; i <= n; i++){
ll tmp;
cin>>tmp;
a[tmp] = 1;
b[P - tmp] = 1;
fac = fac * i % mod;
res = (res * inv(fac)) % mod;
res = (res * (1 + tmp)) % mod;
}
// ===================================
limit = 1; while (limit <= 2*P+1) limit <<= 1, bit++;
// 预处理组合数
for (int i = 0; i < limit; i++)
R[i] = (R[i >> 1] >> 1) | ((i & 1) << (bit - 1));
FFT(a, 1);
FFT(b, 1);
for (int i = 0; i <= limit; i++) {
a[i] = a[i] * b[i];
}
FFT(a, -1);
// ===================================
for (int i = P+1; i < limit; i++) {
int x = (int)(a[i].x + 0.5);
if(x > 0){
res = res * power(abs(i - P), x) % mod;
}
}
cout<<res;
return 0;
}