题解:
放完前$i-1$个数之后,$i$会让前面的数变成一个整体,而且与后面没有影响。
就有了$dp$方程:$$dp[i]=\sum(k^2*dp[i-k]*(k-1)!*C(i-1,k-1))$$
拆开组合数之后有这个东西:$$\frac{dp[i]}{(i-1)!}=\sum(\frac{dp[i-k]}{(i-k)!}*k^2)$$
于是就开心的去写$CDQ$了。
代码:
#include#include #include using namespace std;const int MOD = 998244353;const int N = 150000;typedef long long ll;ll fastpow(ll x,int y){ ll ret = 1; while(y) { if(y&1)ret=ret*x%MOD; x=x*x%MOD; y>>=1; } return ret;}int to[4*N],lim=1,L=0;ll inv,W[4*N];void ntt(ll *a,int len,int k){ for(int i=0;i >1);i++)swap(a[i],a[len-i]); for(int i=0;i >1; divi(l,mid); lim = 1,L = 0; while(lim<=(r-l+1))lim<<=1,L++; for(int i=1;i >1]>>1)|((i&1)<<(L-1))); inv = fastpow(lim,MOD-2); for(int i=1;i <<=1)W[i]=fastpow(3,(MOD-1)/(i<<1)); for(int i=0;i 0) printf("%I64d\n",dp[x]); return 0;}