BZOJ3684 大朋友和多叉樹(多項式相關計算)

2022-04-30 04:54:09 字數 1946 閱讀 8125

設$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...