题目描述:
题目分析:
第一种是链式法则,第二种是
(
u
v
)
′
=
u
′
v
+
u
v
′
(uv)'=u'v+uv'
(uv)′=u′v+uv′
令
f
i
=
P
n
(
x
)
[
i
]
f_i=P^n(x)[i]
fi=Pn(x)[i],
g
i
=
P
(
x
)
[
i
]
g_i=P(x)[i]
gi=P(x)[i],已知
g
g
g且最高项次数为
k
k
k,我们要求
f
f
f的前
X
X
X项
首先将第二个式子的第二项移到左边,可以得到:
n
P
n
(
x
)
P
′
(
x
)
=
(
P
n
(
x
)
)
′
P
(
x
)
nP^n(x)P'(x)=(P^n(x))'P(x)
nPn(x)P′(x)=(Pn(x))′P(x)
即
n
∑
i
=
0
t
f
i
∗
(
t
−
i
+
1
)
∗
g
t
−
i
+
1
=
∑
i
=
0
t
(
i
+
1
)
∗
f
i
+
1
∗
g
t
−
i
n\sum_{i=0}^tf_i*(t-i+1)*g_{t-i+1}=\sum_{i=0}^{t}(i+1)*f_{i+1}*g_{t-i}
ni=0∑tfi∗(t−i+1)∗gt−i+1=i=0∑t(i+1)∗fi+1∗gt−i
可以发现求导之后右边出现了
f
t
+
1
f_{t+1}
ft+1这一项,我们把它提出来,并按照
g
g
g的顺序书写右边:
f
t
+
1
∗
(
t
+
1
)
∗
g
0
=
∑
i
=
1
k
n
∗
g
i
∗
i
∗
f
t
−
i
+
1
−
g
i
∗
(
t
−
i
+
1
)
∗
f
t
−
i
+
1
=
∑
i
=
1
k
g
i
∗
f
t
−
i
+
1
∗
(
(
n
+
1
)
i
−
t
−
1
)
f_{t+1}*(t+1)*g_0=\sum_{i=1}^kn*g_i*i*f_{t-i+1}-g_i*(t-i+1)*f_{t-i+1}\\ =\sum_{i=1}^kg_i*f_{t-i+1}*((n+1)i-t-1)
ft+1∗(t+1)∗g0=i=1∑kn∗gi∗i∗ft−i+1−gi∗(t−i+1)∗ft−i+1=i=1∑kgi∗ft−i+1∗((n+1)i−t−1)
这样我们就可以用
O
(
k
)
O(k)
O(k)的时间求出下一项,总复杂度
O
(
k
X
)
O(kX)
O(kX),不难发现这是求k次多项式的n次幂的前x项系数的通用方法。
Code:
#include<bits/stdc++.h>
#define maxn 10000005
using namespace std;
const int mod = 998244353;
int n,K,X,ans,sum,f[maxn],p[maxn],inv[maxn];
inline int Pow(int a,int b){
int s=1; for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) s=1ll*s*a%mod;
return s;
}
int main()
{
scanf("%d%d%d",&n,&K,&X);
for(int i=0;i<=K;i++) scanf("%d",&p[i]),sum+=p[i];
for(int i=0,Iv=Pow(sum,mod-2);i<=K;i++) p[i]=1ll*p[i]*Iv%mod;
inv[0]=inv[1]=1; int Iv0=Pow(p[0],mod-2);
sum=f[0]=Pow(p[0],n);
for(int i=1;i<X;i++){
if(i>1) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(int j=1;j<=K&&j<=i;j++) f[i]=(f[i]+(1ll*(n+1)*j-i)%mod*p[j]%mod*f[i-j])%mod;
f[i]=1ll*f[i]*inv[i]%mod*Iv0%mod;
ans=(ans+1ll*f[i]*i)%mod;
sum=(sum+f[i])%mod;
}
printf("%d\n",((ans+(1ll-sum)*X)%mod+mod)%mod);
}