設$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)$的復合逆,即$g(f(x))=x$
在本題中,$g(x)=x-\sum_x^k$
我們需要多項式求逆和多項式快速冪。
多項式求逆就不介紹了,多項式快速冪一種樸素的做法是倍增+ntt,複雜度是$o(n\log n\log k)$
有沒有更快的做法呢?
觀察到$f(x)^n=e^$,所以我們只需要快速算$\ln(f(x))$及$e^$即可。
注意$f(x)$的常數項要為1,還好出題人良心保證了這一點。
part 1:如何算$\ln(f(x))$?
設$g(x)=\ln(f(x))$,那麼$g'(x)=\frac$,所以$g(x)=\int\frac$,時間複雜度$o(n\log n)$
part 2:如何算$e^$?
還是考慮倍增,假設我已經求出$g_0(x)=e^(mod\;x^n)$,要求$g(x)=e^(mod\;x^)$
根據泰勒展開,有$$0=h(g(x))=\sum_^\frac(g_0(x))}(g(x)-g_0(x))^i$$當$i>1$時,上式$mod\;x^$為$0$
所以$0=h(g_0(x))+h'(g_0(x))(g(x)-g_0(x))\;(mod\;x^)$
即$g(x)=g_0(x)-\frac(mod\;x^)$
其中$h(g(x))=\ln(g(x))-f(x)$
所以$g(x)=g_0(x)-\frac}=g_0(x)(1-\ln(g_0(x))+f(x))\;(mod\;x^)$
時間複雜度$o(n\log n)$
#include #include#include
#define pre m=n<<1; for(int i=0;i>1]>>1)|((i&1)long
long
ll;const
int p=950009857,n=300000
;int
n,m,l,x,nn,f[n],g[n],t1[n],t2[n],t3[n],r[n],ni[n];
ll pw(ll a,
int b)
void ntt(int *a,int n,int
f)
if(!~f) for(int i=0;ip;
}void inv(int *f,int *g,int *t,int n,int
l) inv(f,g,t,n>>1,l-1),memcpy(t,f,sizeof(int)*n),memset(t+n,0,sizeof(int)*n),pre;ntt(t,m,1),ntt(g,m,1
);
for(int i=0;i2-(ll)t[i]*g[i]%p+p)%p;
ntt(g,m,-1),memset(g+n,0,sizeof(int)*n);
}void ln(int *f,int *g,int *t,int n,int
l) void ex(int *f,int *g,int *t,int n,int
l) ex(f,g,t,n>>1,l-1),memset(t,0,sizeof(int)*n*2
),ln(g,t,t2,n,l);
for(int i=0;ip;
t[0]=(t[0]+1)%p,pre;ntt(t,m,1),ntt(g,m,1
);
for(int i=0;ip;
ntt(g,m,-1),memset(g+n,0,sizeof(int)*n);
}int
main()
BZOJ3684 大朋友和多叉樹
我們的大朋友很喜歡電腦科學,而且尤其喜歡多叉樹。對於一棵帶有正整數點權的有根多叉樹,如果它滿足這樣的性質,我們的大朋友就會將其稱作神犇的 點權為1的結點是葉子結點 對於任一點權大於1的結點u,u的孩子數目deg u 屬於集合d,且u的點權等於這些孩子結點的點權之和。給出乙個整數s,你能求出根節點權值...
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...