【洛谷2791】幼儿园篮球题(第二类斯特林数,NTT)
题面
洛谷
题解
对于每一组询问,要求的东西本质上就是:
\[\sum_{i=0}^{k}{m\choose i}{n-m\choose k-i}i^L \]
如果没有后面那个部分,就是一个范德蒙恒等式,所以就要把这个\(i^L\)直接拆掉。
然后直接拿第二类斯特林数来拆:
\[i^L=\sum_{j=0}^L\begin{Bmatrix}L\\j\end{Bmatrix}{i\choose j}j! \]
于是就把答案拆成了:
\[\begin{aligned} Ans&=\sum_{i=0}^k{m\choose i}{n-m\choose k-i}i^L\\ &=\sum_{i=0}^{k}{m\choose i}{n-m\choose k-i}\sum_{j=0}^L\begin{Bmatrix}L\\j\end{Bmatrix}{i\choose j}j!\\ &=\sum_{j=0}^L\begin{Bmatrix}L\\j\end{Bmatrix}j!\sum_{i=0}^{k}{m\choose i}{n-m\choose k-i}{i\choose j} \end{aligned}\]
然后发现\(\displaystyle {m\choose i}{i\choose j}={m\choose j}{m-j\choose i-j}\)
然后就有:
\[\begin{aligned} Ans&=\sum_{j=0}^L\begin{Bmatrix}L\\j\end{Bmatrix}j!{m\choose j}\sum_{i=0}^{k}{n-m\choose k-i}{m-j\choose i-j}\\ &=\sum_{j=0}^L\begin{Bmatrix}L\\j\end{Bmatrix}j!{m\choose j}{n-j\choose k-j}\\ \end{aligned}\]
这样子可以做到单次\(O(L)\)。
于是预处理第二类斯特林数就行了。
这题不知道为什么要卡常,不太理解卡常的意义合在......
#include
#include
#include
using namespace std;
#define MOD 998244353
#define MAX 524288
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
int W[MAX],r[MAX];
void NTT(int *P,int opt,int len)
{
int l=0,N;for(N=1;N>1]>>1)|((i&1)<<(l-1));
for(int i=0;i