题目描述
题解
可以列出式子
∑
i
=
0
k
(
i
m
)
(
k
−
i
n
−
m
)
i
L
(
k
n
)
\frac{\sum_{i=0}^k(_i^m)(_{k-i}^{n-m})i^L}{(_k^n)}
(kn)∑i=0k(im)(k−in−m)iL
我们只关心上面那部分,套路把
i
L
i^L
iL 换掉,得
∑
i
=
0
k
(
i
m
)
(
k
−
i
n
−
m
)
∑
j
=
0
L
{
j
L
}
(
j
i
)
j
!
\sum_{i=0}^k(_i^m)(_{k-i}^{n-m})\sum_{j=0}^L\{_j^L\}(_j^i)j!
i=0∑k(im)(k−in−m)j=0∑L{jL}(ji)j!
把
j
j
j 提前,得
∑
j
=
0
L
{
j
L
}
j
!
∑
i
=
0
k
(
i
m
)
(
k
−
i
n
−
m
)
(
j
i
)
\sum_{j=0}^L\{_j^L\}j!\sum_{i=0}^k(_i^m)(_{k-i}^{n-m})(_j^i)
j=0∑L{jL}j!i=0∑k(im)(k−in−m)(ji)
由于
(
i
m
)
(
j
i
)
=
(
j
m
)
(
i
−
j
m
−
j
)
(_i^m)(_j^i)=(_j^m)(_{i-j}^{m-j})
(im)(ji)=(jm)(i−jm−j) ,于是我们接着化
∑
j
=
0
L
{
j
L
}
j
!
(
j
m
)
∑
i
=
0
k
(
i
−
j
m
−
j
)
(
k
−
i
n
−
m
)
\sum_{j=0}^L\{_j^L\}j!(_j^m)\sum_{i=0}^k(_{i-j}^{m-j})(_{k-i}^{n-m})
j=0∑L{jL}j!(jm)i=0∑k(i−jm−j)(k−in−m)
我们观察到后面的式子,考虑其意义,就是在
m
−
j
m-j
m−j 个中选
i
−
j
i-j
i−j 个数乘上在
n
−
m
n-m
n−m 个数中选出
k
−
i
k-i
k−i 个数的总方案数,由于
i
i
i 是从
0
0
0 到
k
k
k ,所以可以看成是在
n
−
j
n-j
n−j 个数中选出
k
−
j
k-j
k−j 个数,于是我们得到式子
∑
j
=
0
L
{
j
L
}
j
!
(
j
m
)
(
k
−
j
n
−
j
)
\sum_{j=0}^L\{_j^L\}j!(_j^m)(_{k-j}^{n-j})
j=0∑L{jL}j!(jm)(k−jn−j)
于是我们可以预处理
{
j
L
}
\{_j^L\}
{jL} 即可
代码
#include <bits/stdc++.h>
using namespace std;
const int N=8e5+5,M=2e7+5,P=998244353;
int n,m,T,L,G[2]={3,(P+1)/3},A[N],B[N],jc[M],ny[M],t=1,p,r[N];
int X(int x){return x>=P?x-P:x;}
int K(int x,int y){
int z=1;
for (;y;y>>=1,x=1ll*x*x%P)
if (y&1) z=1ll*z*x%P;
return z;
}
void Ntt(int *g,bool o){
for (int i=0;i<t;i++)
if (i<r[i]) swap(g[i],g[r[i]]);
for (int wn,i=1;i<t;i<<=1){
wn=K(G[o],(P-1)/(i<<1));
for (int x,y,j=0;j<t;j+=(i<<1))
for (int w=1,k=0;k<i;k++,w=1ll*w*wn%P)
x=g[j+k],y=1ll*w*g[i+j+k]%P,
g[j+k]=X(x+y),g[i+j+k]=X(x-y+P);
}
if (o)
for (int i=0,v=K(t,P-2);i<t;i++)
g[i]=1ll*v*g[i]%P;
};
int main(){
cin>>n>>m>>T>>L;
n=max(n,L);jc[0]=1;
for (int i=1;i<=n;i++)
jc[i]=1ll*i*jc[i-1]%P;
ny[n]=K(jc[n],P-2);
for (int i=n;i;i--)
ny[i-1]=1ll*i*ny[i]%P;
for (int i=0,F=1;i<=L;i++,F=P-F)
A[i]=1ll*F*ny[i]%P,
B[i]=1ll*K(i,L)*ny[i]%P;
for (;t<L+L+2;t<<=1,p++);
for (int i=0;i<t;i++)
r[i]=(r[i>>1]>>1)|((i&1)<<(p-1));
Ntt(A,0);Ntt(B,0);
for (int i=0;i<t;i++)
A[i]=1ll*A[i]*B[i]%P;
Ntt(A,1);
for (int x,k,v;T--;){
scanf("%d%d%d",&n,&m,&k);
v=min(min(n,m),min(k,L));x=0;
for (int i=0;i<=v;i++)
x=X(x+1ll*A[i]*ny[m-i]%P*jc[n-i]%P*ny[k-i]%P);
x=1ll*x*jc[m]%P*ny[n]%P*jc[k]%P;
printf("%d\n",x);
}
return 0;
}