Description
有m天时间,每天可以完成任意数量的事件,第i天可以完成的事件有(ui+v)种(可以同一种完成多次)
问m天总共完成n个事件的方案数。
注意每天完成的时间是有顺序的,也就是说同一天内1,2和2,1是两种不同的方案。
T组数据。
n
≤
1
0
18
,
m
≤
200000
,
u
,
v
≤
1
0
9
,
T
≤
5
n\leq 10^{18},m\leq 200000,u,v\leq 10^9,T\leq 5
n≤1018,m≤200000,u,v≤109,T≤5,答案对998244353取模
Solution
容易列出每一天的一般生成函数为 1 1 − ( u i + v ) x 1\over 1-(ui+v)x 1−(ui+v)x1
那么答案就是 ∏ i = 1 m 1 1 − ( u i + v ) x \prod\limits_{i=1}^{m}{1\over 1-(ui+v)x} i=1∏m1−(ui+v)x1中 x n x^n xn这一项的系数
暴力乘或者分治NTT再求逆显然不能通过。
然后我们发现分母是一个常数项为1的多项式
这不禁让我们联想起常系数齐次线性递推
但是m=200000,还有5组数据,实测极限跑一分钟都跑不出来…
然而此时我们发现并没有利用(ui+v)这个性质
这里就有一些技巧了
题解给出了一个组合意义的推导方法,这里我们介绍另外一种。
我们先给出一个结论
最终的多项式
S
(
x
)
=
1
(
u
x
)
m
−
1
∑
i
=
1
m
a
m
,
i
1
−
(
u
i
+
v
)
x
S(x)={1\over (ux)^{m-1}}\sum\limits_{i=1}^{m}{a_{m,i}\over 1-(ui+v)x}
S(x)=(ux)m−11i=1∑m1−(ui+v)xam,i
其中
a
m
,
i
a_{m,i}
am,i是与m,i有关的常数
这是怎么得来的呢?
我们考虑这样一个小学奥数的式子
1
a
×
1
b
=
1
b
−
a
×
(
1
a
−
1
b
)
{1\over a}\times{1\over b}={1\over b-a}\times({1\over a}-{1\over b})
a1×b1=b−a1×(a1−b1)
也就是说我们能将乘化成加减
现在的问题是求出系数
a
a
a,以及搞清楚前面的
1
x
m
−
1
1\over x^{m-1}
xm−11是怎么来的
我们假定已经求出了 S i ( x ) = ∏ j = 1 m 1 1 − ( u j + v ) x = 1 x i − 1 ∑ j = 1 i a i , j 1 − ( u j + v ) x S_i(x)=\prod\limits_{j=1}^{m}{1\over 1-(uj+v)x}={1\over x^{i-1}}\sum\limits_{j=1}^{i}{a_{i,j}\over 1-(uj+v)x} Si(x)=j=1∏m1−(uj+v)x1=xi−11j=1∑i1−(uj+v)xai,j
我们要在末尾乘上
1
1
−
(
u
(
i
+
1
)
+
v
)
x
1\over {1-(u(i+1)+v)x}
1−(u(i+1)+v)x1
考虑它与第j项相乘
(1)
a
i
,
j
1
−
(
u
j
+
v
)
x
×
1
1
−
(
u
(
i
+
1
)
+
v
)
x
\tag 1{a_{i,j}\over 1-(uj+v)x}\times {1\over {1-(u(i+1)+v)x}}
1−(uj+v)xai,j×1−(u(i+1)+v)x1(1)
(2)
=
a
i
,
j
u
x
(
j
−
(
i
+
1
)
)
×
(
1
1
−
(
u
j
+
v
)
x
−
1
1
−
(
u
(
i
+
1
)
+
v
)
x
)
\tag 2={a_{i,j}\over ux(j-(i+1))}\times \left({1\over 1-(uj+v)x}-{1\over {1-(u(i+1)+v)x}}\right)
=ux(j−(i+1))ai,j×(1−(uj+v)x1−1−(u(i+1)+v)x1)(2)
我们发现,分母中的x同时将会出现在后面括号的两项中,因此每加入一个新的i+1,总的式子就会除以x,这就是 1 x m − 1 1\over {x^{m-1}} xm−11的来由,u也是一样的,因此我们可以提出一个 1 u m − 1 1\over u^{m-1} um−11
观察a的变化,我们发现每加入一个(i+1)它就会类似的这样变动
也就是说
(3)
a
i
+
1
,
j
=
a
i
,
j
(
j
−
(
i
+
1
)
)
\tag 3a_{i+1,j}={a_{i,j}\over (j-(i+1))}
ai+1,j=(j−(i+1))ai,j(3)
那么 a m , j = a j , j ( − 1 ) m − j ( m − j ) ! a_{m,j}={a_{j,j}(-1)^{m-j}\over (m-j)!} am,j=(m−j)!aj,j(−1)m−j
现在的问题是计算
a
i
,
i
a_{i,i}
ai,i,记为
f
i
f_i
fi
1~i-1的每一项都会对fi有贡献
容易看出
(4)
f
i
=
∑
j
=
1
i
−
1
a
i
−
1
,
j
u
(
i
−
j
)
=
∑
j
=
1
i
−
1
f
j
(
−
1
)
i
−
1
−
j
(
i
−
j
)
!
=
−
∑
j
=
1
i
−
1
f
j
(
−
1
)
i
−
j
(
i
−
j
)
!
\tag 4f_i=\sum\limits_{j=1}^{i-1}{a_{i-1,j}\over u(i-j)}=\sum\limits_{j=1}^{i-1}{f_j(-1)^{i-1-j}\over (i-j)!}=-\sum\limits_{j=1}^{i-1}{f_j(-1)^{i-j}\over (i-j)!}
fi=j=1∑i−1u(i−j)ai−1,j=j=1∑i−1(i−j)!fj(−1)i−1−j=−j=1∑i−1(i−j)!fj(−1)i−j(4)
设 F ( x ) F(x) F(x)为 f i f_i fi的生成函数,我们可以得到 F ( x ) = F ( x ) e − x + x F(x)=F(x)e^{-x}+x F(x)=F(x)e−x+x(因为第一项不能被转移来)
解得 F ( x ) = x e x F(x)=xe^x F(x)=xex,即 f i = 1 ( i − 1 ) ! f_i={1\over (i-1)!} fi=(i−1)!1
现在有了 f f f,就能相应的计算出 a m , j a_{m,j} am,j,就能求得每一个和式的系数,进而直接利用生成函数 1 1 − a x 1\over 1-ax 1−ax1的第 i i i项为 a i x a^ix aix的性质就能算出答案。
注意由于前面乘了一个 1 x m − 1 1\over x^{m-1} xm−11,因此计算的是 x n + m x^{n+m} xn+m这一项。
时间复杂度 O ( m log n ) O(m\log n) O(mlogn), log n \log n logn是快速幂
Code
#include <bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
#define N 200005
#define LL long long
#define mo 998244353
using namespace std;
int t;
LL n,m,r1,r2,ny[N],js[N];
//prepare
LL ksm(LL k,LL n)
{
k=(k+mo)%mo;
LL s=1;
for(;n;n>>=1,k=k*k%mo) if(n&1) s=s*k%mo;
return s;
}
int main()
{
int t;
cin>>t;
js[0]=1;
fo(i,1,N-5) js[i]=js[i-1]*(LL)i%mo;
ny[N-5]=ksm(js[N-5],mo-2);
fod(i,N-6,0) ny[i]=ny[i+1]*(LL)(i+1)%mo;
while(t--)
{
cin>>n>>m>>r1>>r2;
LL ans=0,v=(m&1)?1:-1,u=ksm(ksm(r1,m-1),mo-2);
fo(i,1,m)
{
ans=(ans+ny[i-1]*v*ny[m-i]%mo*ksm(r1*(LL)i%mo+r2,n+m-1)%mo*u%mo)%mo,v=-v;
}
printf("%lld\n",(ans+mo)%mo);
}
}