我們的大朋友很喜歡電腦科學,而且尤其喜歡多叉樹。對於一棵帶有正整數點權的有根多叉樹,如果它滿足這樣的性質,我們的大朋友就會將其稱作神犇的:點權為1的結點是葉子結點;對於任一點權大於1的結點u,u的孩子數目deg[u]屬於集合d,且u的點權等於這些孩子結點的點權之和。
給出乙個整數s,你能求出根節點權值為s的神犇多叉樹的個數嗎?請參照樣例以更好的理解什麼樣的兩棵多叉樹會被視為不同的。
我們只需要知道答案關於950009857(453*2^21+1,乙個質數)取模後的值。
m,s<=100000
樣例告訴我們兒子是有順序的
設f(x)為答案的生成函式,那麼我們有f(
x)=∑
i∈sf
i(x)
+xf (x
)=∑i
∈sfi
(x)+
x考慮寫成復合逆的形式,f(
x)−∑
i∈sf
i(x)
=xf (x
)−∑i
∈sfi
(x)=
x把f(x)用x替換,設左邊的生成函式為g(x),那麼f(x)和g(x)互為復合逆
拉格朗日反演:[x
n]f(
x)=1
n[xn
−1](
xg(x
))n [xn
]f(x
)=1n
[xn−
1](x
g(x)
)n
發現右邊x/g(x)的常數項是1,於是我們可以用求ln再求exp的方式來做快速冪
然後就寫多項式全家桶嘍
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int n=4e5+5,mo=950009857;
int pwr(int
x,int
y) ll t[n],w[n];
void dft(ll *a,int len,int flag)
for(int
m=2;m
<=len;m
<<=1) }}
for(int i=0;iif (flag==-1)
}ll c[n];
void get_inv(ll *a,ll *b,int n)
get_inv(a,b,n>>1);
int len=n<<1;
fo(i,0,n-1) c[i]=a[i];fo(i,n,len-1) c[i]=0;
fo(i,(n>>1),len-1) b[i]=0;
dft(c,len,1);dft(b,len,1);
fo(i,0,len-1) b[i]=(2
*b[i]-b[i]*b[i]%mo
*c[i])%mo;
dft(b,len,-1);
fo(i,n,len-1) b[i]=0;
}ll f[n],g[n];
void get_ln(ll *a,ll *b,int n)
ll h[n];
void get_exp(ll *a,ll *b,int n)
get_exp(a,b,n>>1);
get_ln(b,h,n);
fo(i,0,n-1) h[i]=(a[i]-h[i]+mo)%mo;
(h[0]=h[0]+1)%=mo;
int len=n<<1;
fo(i,n,len-1) h[i]=b[i]=0;
dft(h,len,1);dft(b,len,1);
fo(i,0,len-1) b[i]=b[i]*h[i]%mo;
dft(b,len,-1);
fo(i,n,len-1) b[i]=0;
}ll h[n];
void get_pow(ll *a,int n,int
m) int n,m,x,len;
ll f[n],g[n];
int main()
g[0]++;
get_inv(g,f,len);
get_pow(f,len,n);
ll ans=f[n-1]*pwr(n,mo-2)%mo;
printf("%lld\n",(ans+mo)%mo);
return
0;}
BZOJ3684 大朋友和多叉樹(多項式相關計算)
設 f x 為樹的生成函式,即 x i 的係數為根節點權值為 i 的樹的個數。不難得出 f x sum f x k x 我們要求這個多項式的第 n 項,由拉格朗日反演可得 x n f x frac1n x frac x n 其中 x n f x 表示 f x 的 n 次項係數。f x 是 g x 的...
BZOJ3684 大朋友和多叉樹(拉格朗日反演)
很顯然地,我們考慮生成函式,由於必須兒子不能為空,所以顯然0 00個點的方案數我們需要設定為0 00。設f x f x f x 為合法的樹的生成函式,則有 f x x i d fi x f x x sum f i x f x x i d fi x 設g x 1 i d xi g x 1 sum x ...
BZOJ3625小朋友和二叉樹 生成函式
f的常數項為1,g的常數項為0,帶入方程,捨去減的根。說是因為不收斂?多項式開根 求逆 code附贈兩種開根寫法 include define pf printf define sf scanf define cs const define ll long long define db double...