洛谷P2791 幼儿园篮球题
题解
可以列出式子$$\frac{\sum_{i=0}^k(_i^m)(_{k-i}^{n-m})i^L}{(_k^n)}$$
我们只关心上面那部分,套路把 $i^L$ 换掉,得$$\sum_{i=0}^k(_i^m)(_{k-i}^{n-m})\sum_{j=0}^L\{_j^L\}(_j^i)j!$$
把 $j$ 提前,得$$\sum_{j=0}^L\{_j^L\}j!\sum_{i=0}^k(_i^m)(_{k-i}^{n-m})(_j^i)$$
由于 $(_i^m)(_j^i)=(_j^m)(_{i-j}^{m-j})$ ,于是我们接着化$$\sum_{j=0}^L\{_j^L\}j!(_j^m)\sum_{i=0}^k(_{i-j}^{m-j})(_{k-i}^{n-m})$$
我们观察到后面的式子,考虑其意义,就是在 $m-j$ 个中选 $i-j$ 个数乘上在 $n-m$ 个数中选出 $k-i$ 个数的总方案数,由于 $i$ 是从 $0$ 到 $k$ ,所以可以看成是在 $n-j$ 个数中选出 $k-j$ 个数,于是我们得到式子$$\sum_{j=0}^L\{_j^L\}j!(_j^m)(_{k-j}^{n-j})$$
于是我们可以预处理 $\{_j^L\}$ 即可
代码
#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; }