【生成函式+多項式求逆】LGP5162 WD與積木
阿新 • • 發佈:2019-01-05
【題目】
原題地址
有
塊積木,給每塊積木隨機一個大小並標號,然後將相同大小的積木放在一層,再從大到小堆起來。我們只關心積木的相對大小,因此所有堆法等概率出現,求期望層數。
【解題思路】
從期望的定義入手,我們先考慮一個樸素的
:設
表示有
塊積木時產生層數和,
表示
塊積木不同堆法的數量,答案就是
,其中
。我們列舉第一層放幾塊積木可以得到轉移:
這樣做是
的,這裡好像還有一個標號順序的問題我們好像沒有考慮,但由於方案和層數是一一對應的,所以相當於同時約掉了。
我們考慮一個更為正確的寫法:不妨設
由於沒有組合數的計算,我們這裡寫出的生成函式要考慮順序(實際上和前幾天的生成函式題類似,答案的形式都是
)
我們可以得到
於是多項式求逆可以做到
【參考程式碼】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,M=264233;
const int mod=998244353,G=3;
int fac[M],ifac[M];
int read()
{
int ret=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) ret=ret*10+(c^48),c=getchar();
return ret;
}
int qpow(int x,int y)
{
int res=1;
for(;y;y>>=1,x=(ll)x*x%mod) if(y&1) res=(ll)res*x%mod;
return res;
}
int upm(int x){return x>=mod?x-mod:(x<0?x+mod:x);}
void up(int &x,int y){x=upm(x+y);}
namespace NTT
{
int m,L;
int f[M],g[M],h[M],t[M],t2[M];
int rev[M];
void reget(int n)
{
for(L=0,m=1;m<2*n;++L,m<<=1);
for(int i=0;i<m;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
}
void ntt(int *a,int n,int op)