Title effect: arrangement of n number, to each number after the first point even greater than its edges, is arranged in the weight of each square block sizes Unicom, find all permutations and weights.
Ideas:
Consider arranged directly dp [i] represents the answer when n = i.
We consider again after the insertion is done and n n-1 before the number, you will find all numbers are in front of n and it Unicom.
So dp equations arise:
$dp[n]=\Sigma(dp[n-k]*k^{2}*(k-1)!*C_{n-1}^{k-1})$
The number of combinations and shift over to become:
$\frac{dp[n]}{(n-1)!}=\Sigma(\frac{dp[n-k]}{(n-k)!}*k^{2})$
Divide and Conquer get FFT.
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 typedef long long lint; 6 const lint mo=998244353; 7 const int N=600069; 8 lint fpow(lint a,lint p) 9 { 10 lint ret=1; 11 while(p) 12 { 13 if(p&1ll) (ret*=a)%=mo; 14 (a*=a)%=mo; 15 p>>=1; 16 } 17 return ret; 18 } 19 lint fac[N],ifac[N],i2[N]; 20 lint dp[N]; 21 22 int inv[N]; 23 lint wg[N],iwg[N]; 24 void ntt(lint *a,int len,int tp) 25 { 26 lint ilen=fpow(len,mo-2); 27 for(int i=0;i<len;i++) if(i<inv[i]) swap(a[i],a[inv[i]]); 28 for ( int i = 1 het; i <; i << = 1 ) 29 { 30 lint w0 ~ = (TP)? WG [i]: whether [i]; 31 for ( int j = 0 ; j <het; j = (i << 1 )) 32 { 33 lint p = 1 ; 34 for ( int k = 0 ; k <i; k ++, (w * = w0)% = I) 35 { 36 lint W1 = a [j + k], W2 = p * a [j + k + i]% I; 37 a [j + k] = (W1 + W2)%, a [j + k + i] = (W1-W2 +)%mo; 38 } 39 } 40 } 41 if(tp==-1) for(int i=0;i<len;i++) (a[i]*=ilen)%=mo; 42 } 43 lint a[N],b[N],c[N]; 44 void cdq(int l,int r) 45 { 46 if(l==r) {(dp[l]*=(l?fac[l-1]:1))%=mo;return;} 47 int mm=l+r>>1; 48 cdq(l,mm); 49 int len=1,pl=0,n=r-l+1; 50 while(len<=n) len<<=1,pl++; 51 for(int i=1;i<len;i++) inv[i]=(inv[i>>1]>>1)|((i&1)<<(pl-1)); 52 for(int i=0;i<len;i++) a[i]=b[i]=0; 53 for(int i=0;i<mm-l+1;i++) a[i]=dp[i+l]*ifac[i+l]%mo; 54 for(int i=0;i<r-l+1;i++) b[i]=i2[i]; 55 ntt(a,len,1),ntt(b,len,1); 56 for(int i=0;i<len;i++) c[i]=a[i]*b[i]%mo; 57 ntt(c,len,-1); 58 for(int i=mm+1;i<=r;i++) (dp[i]+=c[i-l])%=mo; 59 cdq(mm+1,r); 60 } 61 62 63 int xi,T; 64 int main () 65 { 66 college [ 0 ] = ifac [ 0 ] = 1 ; 67 for ( int i = 1 ; i <= 100,000 ; i ++) college [i] = college [i- 1 ] *%, I ifac [i] = fpow (college [i], the followers 2 ), i2 [ i] = 1ll * i * i% ; 68 for ( int i = 1 ; i < 524288 ; << = 1 ) WG [i] = fpow ( 3 , (know - 1 ) / (<< 1 )), that you have [i] = fpow (WG [ i], the followers 2 ); 69 DP [ 0]=1; 70 cdq(0,100000); 71 while(scanf("%d",&xi)!=EOF) printf("%lld\n",dp[xi]); 72 return 0; 73 }