很顯然地,我們考慮生成函式,由於必須兒子不能為空,所以顯然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^i
g(x)=1
−∑i∈
dxi
,則顯然g(f
(x))
=x
g(f(x))=x
g(f(x)
)=x,即g,f
g,fg,
f互為復合逆。
發現我們並不需要求整個f
ff,只需要求第s
ss項的係數,考慮拉格朗日反演:
[ xs
]f(x
)=1s
[x−1
](1g
(x))
s=1s
[xs−
1](x
g(x)
)s
[x^s]f(x)=\frac[x^](\frac)^s=\frac[x^](\frac)^s
[xs]f(
x)=s
1[x
−1](
g(x)
1)s
=s1
[xs−
1](g
(x)x
)s
多項式快速冪即可。
**:
#include
#define ll long long
#define re register
#define cs const
using std::cerr;
using std::cout;
cs int mod=
950009857
;inline
intadd
(int a,
int b)
inline
intdec
(int a,
int b)
inline
intmul
(int a,
int b)
inline
intpower
(int a,
int b,
int res=1)
inline
void
inc(
int&a,
int b)
inline
void
dec(
int&a,
int b)
inline
void
mul(
int&a,
int b)
typedef std::vector<
int> poly;
cs int bit=
21,size=
1<<20|
1;int r[size]
,*w[bit+1]
;int fac[size]
,ifac[size]
,inv[size]
;inline
void
init_ntt()
}inline
void
ntt(poly &a,
int len,
int typ)
if(typ==-1
)}inline
void
init_rev
(int l)
inline poly operator
*(poly a,poly b)
inline poly inv
(cs poly &a,
int lim)
b.resize
(lim)
;return b;
}inline poly inv
(cs poly &a)
inline poly deriv
(poly a)
inline poly integ
(poly a)
inline poly ln
(poly a,
int lim)
inline poly ln
(cs poly &a)
inline poly exp
(cs poly &a,
int lim)
b.resize
(lim)
;return b;
}inline poly exp
(cs poly &a)
inline poly ksm
(poly a,
int k)
poly g;
signed
main()
BZOJ3684 大朋友和多叉樹
我們的大朋友很喜歡電腦科學,而且尤其喜歡多叉樹。對於一棵帶有正整數點權的有根多叉樹,如果它滿足這樣的性質,我們的大朋友就會將其稱作神犇的 點權為1的結點是葉子結點 對於任一點權大於1的結點u,u的孩子數目deg u 屬於集合d,且u的點權等於這些孩子結點的點權之和。給出乙個整數s,你能求出根節點權值...
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 的...
BZOJ3625小朋友和二叉樹 生成函式
f的常數項為1,g的常數項為0,帶入方程,捨去減的根。說是因為不收斂?多項式開根 求逆 code附贈兩種開根寫法 include define pf printf define sf scanf define cs const define ll long long define db double...