CF Round#698 Div1. Nezzar and Chocolate Bars 前言 这就是大道至简吗。。
为什么和某ZJOI开关一样,到最后就是个背包。。
 
题目大意: 给定$n,K$和一些棍子长度为$l_i(i\in [1,n])$(实数!)
每次随机选择一根棍子,概率与$l_i$成正比,然后随机分裂成两段(实数!)
一直分裂,直到每根棍子$l_i\leq K$,求期望分裂次数
根据题意容易归纳一个更直观的模型:
把这些$l_i$排在数轴上,初始时,点集为$0,l_1,l_1+l_2,\ldots$
每次随机在数轴上撒一个点,直到点集中相邻两点距离$\leq K$为止
考虑从简单情况入手
n=1 单棍情况,设长度为$L$,考虑期望的简单等价变换
$\displaystyle E(\text{条件第一次成立操作数})=\sum_{i=0}^{\infty} P(i次操作条件未成立)$
设$P_n$为操作$n$次成立(不是恰好)的概率 (变量名重了不要介意)
设$n$次操作后的点集排列之后为$X_i$,其中$X_0=0,X_{n+1}=L$
我们要求$\forall i\in[1,n+1],Z_i=X_i-X_{i-1}\leq K$,考虑用一个二项式反演来解决这个计算
设$W=\lfloor \frac{L} {K}\rfloor$
$\displaystyle P_n=\frac{1} {L^n}\sum_{i=0}^{W} (-1)^i\binom{n+1} {i}(L-iK)^n$
其意义即为从分成的$n+1$个$Z_i$中选择$i$个强制不合法,然后剩下的随意分布,由此计算概率
一般情形 考虑一样的期望转概率,设$p_m$为$m$次完成的概率,$q_m=1-p_m$
$\displaystyle q_m=\sum_{j_1+j_2+\cdots +j_n=m} \frac{m!} {j_1!j_2!\cdots j_n!}\prod (\frac{l_i} {\sum l_k})^{j_i}P_{i,j_i}$
显然这里考虑用$\text{EGF}$积的形式来表示,设$S=\sum l_i$
回到上一步,这里我们对于$i,l_i$计算其$P_n$加上$\frac{l_i} {S}$系数的$\text{EGF}$,沿用上面的$L=l_i$
$\displaystyle F_i(x)=\text{EGF(P)}=\sum_{n\ge 0}\frac{1} {n!}(\frac{L} {S})^n\sum_{i=0}^W(-1)^{i}\binom{n+1} {i}(1-i\frac{K} {L})^{n}x^n$
$\displaystyle F_i(x)=\sum_{n\ge 0}\frac{1} {n!}\sum_{i=0}^W(-1)^{i}\binom{n+1} {i}(\frac{L-iK} {S})^{n}x^n$
设$\displaystyle u=\frac{L-iK} {S}x$
$\displaystyle F_i(x)=\sum_{i=0}^W\frac{(-1)^{i} } {i!}\sum_{n\ge i-1}\frac{n+1} {(n+1-i)!}u^n$
令$n’=n+1-i$,$n=n’+i-1$,将$n’$带入
$\displaystyle F_i(x)=\sum_{i=0}^W\frac{(-1)^{i} } {i!}\sum_{n\ge 0}\frac{n+i} {n!}u^{n+i-1}$
将$n,i$拆开
$\displaystyle F_i(x)=\sum_{i=0}^W \frac{(-1)^{i} } {i!}(u^{i}\sum_{n\ge 0}\frac{1} {n!}u^{n}+u^{i-1}\sum_{n\ge 0}\frac{i} {n!}u^{n})$
$\displaystyle F_i(x)=\sum_{i=0}^W \frac{(-1)^{i} } {i!}(u^{i}+iu^{i-1})e^u$
容易发现我们需要多项式是$F(x)=e^x-\prod F_i(x)$
最终$F(x)$的每一项,都会是$x^k e^{cx}$的形式
其中$e^u$中的$u$总是$\frac{1} {S}(L-iK)x$,合并之后$L$之和总是存在,记录$\sum i$即可,为$O(S)$
而每项要么是$u^ie^u$要么是$u^{i-1}e^u$,可以考虑记录一下$u^{i-1}e^u$出现的次数,为$O(n)$
我们的多项式项数是$O(nS)$的
最终我们还需要对于每一项计算答案
我们要计算$\displaystyle \sum_{n\ge 0}n![x^n]F(x)$,考虑形如$x^ke^{cx}$一项的贡献
$\displaystyle \sum_{n\ge k}n =\sum_{n\ge k}\frac{n!} {(n-k)!}c^{n-k}=k!\sum_{n\ge 0}\binom{n+k} {n}c^{n}$
由于$\displaystyle \binom{n+k} {n}=(-1)^{n}\binom{-k-1} {n}$
带入广义二项式定理得到
$\displaystyle k!\sum_{n\ge 0}\binom{n+k} {n}c^{n}=k!(1-c)^{-k-1}$
根据是否用$\text{NTT}$优化,复杂度会有所不同
over.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 #include <bits/stdc++.h>  using  namespace  std;typedef  double  db;typedef  long  double  ldb;typedef  long  long  ll;typedef  unsigned  long  long  ull;#define  reg register #define  pb push_back #define  mp make_pair #define  Mod1(x) ((x>=P)&&(x-=P)) #define  Mod2(x) ((x<0)&&(x+=P)) #define  rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i) #define  drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i) template  <class  T >  inline  void  cmin (T &a,const  T &b)  { ((a>b)&&(a=b)); }template  <class  T >  inline  void  cmax (T &a,const  T &b)  { ((a<b)&&(a=b)); }char  IO;template  <class  T =int > T rd ()  {    T s=0 ; int  f=0 ;     while (!isdigit (IO=getchar ())) if (IO=='-' ) f=1 ;     do  s=(s<<1 )+(s<<3 )+(IO^'0' );     while (isdigit (IO=getchar ()));     return  f?-s:s; } const  int  N=1 <<11 |10 ,P=998244353 ;int  n,m,k;ll qpow (ll x,ll k=P-2 )   {    ll res=1 ;     for (;k;k>>=1 ,x=x*x%P) if (k&1 ) res=res*x%P;     return  res; } int  rev[N],I[N],J[N];typedef  vector <int > V;void  Init ()  {    rep (i,J[0 ]=1 ,N-1 ) J[i]=1ll *J[i-1 ]*i%P;     I[N-1 ]=qpow (J[N-1 ]);     drep (i,N-1 ,1 ) I[i-1 ]=1ll *I[i]*i%P; } int  Init (int  n)  {    int  R=1 ,c=-1 ;     while (R<=n) R<<=1 ,c++;     rep (i,0 ,R-1 ) rev[i]=(rev[i>>1 ]>>1 )|((i&1 )<<c);     return  R; } void  NTT (int  n,V &a,int  f)   {    static  int  e[N>>1 ];     rep (i,0 ,n-1 ) if (i<rev[i]) swap (a[i],a[rev[i]]);     for (int  i=e[0 ]=1 ;i<n;i<<=1 ) {         ll t=qpow (f==1 ?3 :(P+1 )/3 ,(P-1 )/i/2 );         for (int  j=i-2 ;j>=0 ;j-=2 ) e[j+1 ]=(e[j]=e[j>>1 ])*t%P;         for (int  l=0 ;l<n;l+=i*2 ) {             for (int  j=l;j<l+i;++j) {                 int  t=1ll *e[j-l]*a[j+i]%P;                 a[j+i]=a[j]-t,Mod2 (a[j+i]);                 a[j]+=t,Mod1 (a[j]);             }         }     }     if (f==-1 ) {         ll Inv=1ll *I[n]*J[n-1 ]%P;         rep (i,0 ,n-1 ) a[i]=a[i]*Inv%P;     } } V operator  * (V a,V b){     if (!a.size () || !b.size ()) return  { };     int  n=a.size ()+b.size ()-1 ,R=Init (n);     a.resize (R),b.resize (R);     NTT (R,a,1 ),NTT (R,b,1 );     rep (i,0 ,R-1 ) a[i]=1ll *a[i]*b[i]%P;     NTT (R,a,-1 );     a.resize (n);     return  a; } V operator  + (V a,V b){     if (a.size ()<b.size ()) swap (a,b);     rep (i,0 ,b.size ()-1 ) a[i]+=b[i],Mod1 (a[i]);     return  a; } V F[55 ],A,B; int  S,L[55 ];int  main ()  {    Init ();     n=rd (),k=rd ();     rep (i,1 ,n) S+=L[i]=rd ();     sort (L+1 ,L+n+1 );     int  InvS=qpow (S);     F[0 ]={1 };     rep (i,1 ,n) {         int  W=(L[i]-1 )/k;         A.clear (),A.resize (W+1 );         B.clear (),B.resize (W+1 );                           rep (j,0 ,W) {             int  w=1ll *(L[i]-j*k)*InvS%P;             A[j]=1ll *(j&1 ?P-I[j]:I[j])*qpow (w,j)%P;             if (j) B[j]=1ll *(j&1 ?P-I[j]:I[j])*qpow (w,j-1 )%P*j%P;         }         drep (j,i,0 ) {             if (!j) F[j]=F[j]*A;             else  F[j]=F[j]*A+F[j-1 ]*B;         }     }               int  ans=0 ;     rep (i,0 ,n) {         rep (j,max (i,1 ),F[i].size ()-1 ) if (F[i][j]) {             int  k=j-i;             ans=(ans+1ll *F[i][j]*J[k]%P*qpow (1ll *j*::k*InvS%P,P-1 -k-1 ))%P;         }     }     ans=(P-ans)%P;     printf ("%d\n" ,ans); }