hdu5322 Hope (dp + FFT + partition)

hdu

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 }
View Code

 

Guess you like

Origin www.cnblogs.com/rikurika/p/11670505.html
FFT