题目链接

题意

求满足如下条件的多叉树个数:

1.每一个点的儿子个数在给定的集合 \(S\) 内

2.总的叶子节点树为 \(s\)

儿子之间有顺序关系,但节点是没有标号的。

Sol

拉格朗日反演板子题。

(似乎不像是个反演)


拉格朗日反演:

用来求 复合逆

如果两个多项式 \(F(x),G(x)\) 满足常数项均为 0,一次项均不为 0,并且 \(G(F(x))=x\),那么称 \(F(x)\) 与 \(G(x)\) 互为复合逆(其实就是反函数)。

其中 \(F(x)\) 和 \(G(x)\) 可以互换。

结论如下:

\[[x^n]F(x)=\frac{1}{n}[x^{-1}]\frac{1}{G^n(x)}
\]

证明工作及实际做法:

这个式子里怎么有 \(x^{-1}\) 啊...据说是抽象代数里的,直接懵逼。

先不管这些,假装我们允许下标为负,先来随便乱推一下这个式子。

\[G(F(x))=x
\]

\[\sum_{i=1}a_iF^i(x)=x
\]

这里写成了形式幂级数的形式。

我们两边对 \(x\) 求导。

\[\sum_{i=1}ia_iF^{i-1}(x)F'(x)=1
\]

两边同时除掉 \(F^n(x)\),取 \([x^{-1}]\)(我也不知道我在干什么)

\[[x^{-1}]\sum_{i=1}ia_iF^{i-n-1}(x)F'(x)=[x^{-1}]\frac{1}{F^n(x)}
\]

当 \(i\neq n\) 时,\(F^{i-n-1}(x)F'(x)=\dfrac{\big(F^{i-n}(x)\big)'}{i-n}\)

求导后 \(x^{-1}\) 项系数一定是 0。

所以只考虑 \(i=n\) 的情况。

这时

\[F^{-1}(x)F'(x)=\dfrac{\sum_{i=1} ia_ix^{i-1}}{\sum_{i=1}a_ix^i}
\]

\[F^{-1}(x)F'(x)=\dfrac{\sum_{i=1} ia_ix^{i-1}}{a_1x}·\dfrac{1}{1+\sum_{i=1}\frac{a_{i+1}}{a_1}x^i}
\]

后面那个多项式能够求逆,它的逆的常数项显然为 1,因此不存在 \(-1\) 次方项。

而前面那个多项式的 \([x^{-1}]\) 就是 : \(\frac{a_1}{a_1}=1\)

所以 : \([x^{-1}] F^{-1}(x)F'(x)=1\)

所以由之前的式子:

\([x^{-1}]na_nF^{-1}(x)F'(x)=[x^{-1}]\frac{1}{F^n(x)}\)

那么就证完了:

\[a_n=\frac{1}{n}[x^{-1}]\frac{1}{F^n(x)}
\]

但是我们并没有办法直接求解 \([x^{-1}]\),所以我们可以把下标移动一下。

\[a_n=\frac{1}{n}[x^{n-1}]\frac{x^n}{F^n(x)}
\]

这里面乘了个 \(x^n\),哪里来的 \(x^{n-1}\) 系数啊,然后\(F(x)\)还没有逆我怎么求啊 \(QAQ\)

注意到 \(F(x)\) 常数项为 \(0\),而一次项不为 \(0\)

于是乎:

\[a_n=\frac{1}{n}[x^{n-1}]\frac{1}{\big(\frac{F(x)}{x}\big)^n}
\]

这个好像就有 \(x^{n-1}\)了,而且还有逆,万事大吉。


回到本题,按照小朋友和二叉树的套路直接弄个生成函数。

设 \(F(x)\) 是生成一棵含 \(i\) 个叶子节点的合法的树的这个数列的生成函数 。

生成方式显然就是把一堆子树组合起来。

\[F(x)=x+\sum_{i\in S}F^i(x)
\]

枚举有几个儿子,注意这里我们的下标表示的是叶子个数,所以后面的多项式不用乘上 \(x\) 并且由于一个节点是一个叶子,应该给 \(x^1\) 方项系数加 \(1\)

移个项:

\[F(x)-\sum_{i\in S}F^i(x)=x
\]

发现复合函数!

令 \(G(x)=x-\sum_{i\in S}x^i\)

那么:

\[G(F(x))=x
\]

我们要求的是\(F(x)\)的第 \(s\) 次方项系数然后就是套公式的事了。

什么你说你不想写 多项式快速幂 ?

注意到我们是在 \(bzoj\) 上进行评测,时间限制是总时间。

所以我们直接写倍增快速幂就能在 \(bzoj\) 上通过此题(OWO)。

#include<bits/stdc++.h>
#define Set(a,b) memset(a,b,sizeof(a))
#define Clear(a,_begin_,_end_) for(int i=_begin_;i<_end_;++i) a[i]=0
using namespace std;
const int N=1e5+10,MAXN=N<<2;
const int mod=950009857,phi=mod-1;
template <typename T> inline void init(T&x){
x=0;char ch=getchar();bool t=0;
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
if(t) x=-x;return;
}
typedef long long ll;
template<typename T>inline void Inc(T&x,int y){x+=y;if(x>=mod) x-=mod;return;}
template<typename T>inline void Dec(T&x,int y){x-=y;if(x < 0) x+=mod;return;}
template<typename T>inline int fpow(int x,T k){int ret=1;for(;k;k>>=1,x=(ll)x*x%mod) if(k&1) ret=(ll)ret*x%mod;return ret;}
inline int Sum(int x,int y){x+=y;if(x>=mod) return x-mod;return x;}
inline int Dif(int x,int y){x-=y;if(x < 0 ) return x+mod;return x;}
int rader[MAXN],wn[30],iwn[30],Inv[MAXN];
inline void Calc(){
for(int i=0;i<30;++i) wn[i]=fpow(7,phi/(1<<i)),iwn[i]=fpow(wn[i],mod-2);
Inv[1]=1;for(int i=2;i<MAXN;++i) Inv[i]=(ll)(mod-mod/i)*Inv[mod%i]%mod;return;
}
inline int Init(int n){int len=1,up=-1;while(len<=n)len<<=1,++up;for(int i=1;i<len;++i) rader[i]=(rader[i>>1]>>1)|((i&1)<<up);return len;}
inline void NTT(int*A,int n,int f){
for(int i=1;i<n;++i) if(rader[i]>i) swap(A[i],A[rader[i]]);
for(int i=1,h=1;i<n;++h,i<<=1){
int W= (~f) ? wn[h]:iwn[h];
for(int j=0,p=i<<1;j<n;j+=p)
for(int w=1,k=0;k<i;++k,w=(ll)W*w%mod){
int X=A[j|k],Y=(ll)w*A[j|k|i]%mod;
A[j|k]=Sum(X,Y),A[j|k|i]=Dif(X,Y);
}
}if(!~f) for(int i=0;i<n;++i) A[i]=(ll)A[i]*Inv[n]%mod;
}
int n,m;
inline void Poly_Inv(int*F,int*I,int n){
if(n==1) {I[0]=1;return;}
Poly_Inv(F,I,(n+1)>>1);int len=Init(n<<1);
static int A[MAXN];for(int i=0;i<n;++i) A[i]=F[i];Clear(A,n,len);
NTT(A,len,1);NTT(I,len,1);
for(int i=0;i<len;++i) I[i]=Dif(2ll*I[i]%mod,(ll)I[i]*I[i]%mod*A[i]%mod);
NTT(I,len,-1);Clear(I,n,len);return;
}
int main()
{
Calc();init(n),init(m);
static int A[MAXN],G[MAXN];int x;
for(int i=1;i<=m;++i) init(x),A[x-1]=phi;A[0]=1;
int k=n;G[0]=1;int len=Init(n<<1);
while(k) {
NTT(A,len,1);
if(k&1) {
NTT(G,len,1);
for(int i=0;i<len;++i) G[i]=(ll)G[i]*A[i]%mod;
NTT(G,len,-1);Clear(G,n,len);
}
for(int i=0;i<len;++i) A[i]=(ll)A[i]*A[i]%mod;
NTT(A,len,-1);Clear(A,n,len);k>>=1;
}
Set(A,0);Poly_Inv(G,A,n);
int ans=(ll)A[n-1]*Inv[n]%mod;
cout<<ans<<endl;
return 0;
}

【BZOJ3684】大朋友和多叉树(拉格朗日反演)的更多相关文章

  1. BZOJ 3684: 大朋友和多叉树 [拉格朗日反演 多项式k次幂 生成函数]

    3684: 大朋友和多叉树 题意: 求有n个叶子结点,非叶节点的孩子数量\(\in S, a \notin S\)的有根树个数,无标号,孩子有序. 鏼鏼鏼! 树的OGF:\(T(x) = \sum_{ ...

  2. bzoj3684: 大朋友和多叉树(拉格朗日反演+多项式全家桶)

    题面 传送门 题解 首先你得知道什么是拉格朗日反演->这里 我们列出树的个数的生成函数 \[T(x)=x+\prod_{i\in D}T^i(x)\] \[T(x)-\prod_{i\in D} ...

  3. [BZOJ3684]大朋友和多叉树

    设答案为$f_s$,它的生成函数为$\begin{align*}F(x)=\sum\limits_{i=0}^\infty f_ix^i\end{align*}$,则我们有$\begin{align* ...

  4. BZOJ3684 大朋友和多叉树(多项式相关计算)

    设$f(x)$为树的生成函数,即$x^i$的系数为根节点权值为$i$的树的个数.不难得出$f(x)=\sum_{k\in D}f(x)^k+x$我们要求这个多项式的第$n$项,由拉格朗日反演可得$[x ...

  5. BZOJ 3684 大朋友和多叉树

    BZOJ 3684 大朋友和多叉树 Description 我们的大朋友很喜欢计算机科学,而且尤其喜欢多叉树.对于一棵带有正整数点权的有根多叉树,如果它满足这样的性质,我们的大朋友就会将其称作神犇的: ...

  6. [BZOJ3684][拉格朗日反演+多项式求幂]大朋友和多叉树

    题面 Description 我们的大朋友很喜欢计算机科学,而且尤其喜欢多叉树.对于一棵带有正整数点权的有根多叉树,如果它满足这样的性质,我们的大朋友就会将其称作神犇的:点权为\(1\)的结点是叶子结 ...

  7. 【bzoj3684】 大朋友和多叉树 生成函数+多项式快速幂+拉格朗日反演

    这题一看就觉得是生成函数的题... 我们不妨去推下此题的生成函数,设生成函数为$F(x)$,则$[x^s]F(x)$即为答案. 根据题意,我们得到 $F(x)=x+\sum_{i∈D} F^i(x)$ ...

  8. [拉格朗日反演][FFT][NTT][多项式大全]详解

    1.多项式的两种表示法 1.系数表示法 我们最常用的多项式表示法就是系数表示法,一个次数界为\(n\)的多项式\(S(x)\)可以用一个向量\(s=(s_0,s_1,s_2,\cdots,s_n-1) ...

  9. 【CSA35G】【XSY3318】Counting Quests DP 拉格朗日反演 NTT

    题目大意 zjt 是个神仙. 一天,zjt 正在和 yww 玩猜数游戏. zjt 先想一个 \([1,n]\) 之间的整数 \(x\),然后 yww 开始向他问问题. yww 每次给 zjt 一个区间 ...

随机推荐

  1. 如何修改eclipse中的maven的仓库地址

    最近的有一个朋友问我如何修改eclipse的maven的本地仓库,我想了一下,这个玩意一般是不用修改的,主要是你本地安装的maven在哪个位置,一般的本地仓库位置在 C:\Users\username ...

  2. Javascript获取html元素的几种方法

    1.通过id获取html元素 <!DOCTYPE html> <html> <head lang="en"> <meta charset= ...

  3. Flume HA

    flume提供fail over和load balance功能 1.添加collector配置(配置两个collector) # Name the components on this agents1 ...

  4. Unity中的动画系统和Timeline(4) AvatarMask和IK动画

    AvatarMask(骨骼遮罩) 在前面角色动画的基础上,角色在奔跑过程中捡起一块木头,双手要抱着这块木头.如果使用前面的方法,直接切换动画,那么就只剩下抱木头的动画,其它动画就没了.这时我们要使用下 ...

  5. tensorflow-2.0 技巧 | ImageNet 归一化

    _MEAN_RGB = [123.15, 115.90, 103.06] def _preprocess_subtract_imagenet_mean(inputs): ""&qu ...

  6. AGC037 C Numbers on a Circle【思维】

    题目传送门 题意 这道题被某大佬改编拿来出成考试题,是长这个样子的: 好的,其实这才是真正的题意: 给定初始序列和最终序列,每次选择一个数变成自己和相邻2个数的和.问初始序列是否可以变为最终序列,若可 ...

  7. 模板if 的使用

    from flask import Flask,render_template app = Flask(__name__) app.debug = True @app.route('/') def h ...

  8. 小记-----如何把本地jar包加载到maven库中

    1.从maven中央库下载下jar包

  9. 使用render函数渲染组件

    使用render函数渲染组件:https://www.jianshu.com/p/27ec4467a66b

  10. 牛逼哄洪的 Java 8 Stream,性能也牛逼么?

    那么,Stream API的性能到底如何呢,代码整洁的背后是否意味着性能的损耗呢?本文对Stream API的性能一探究竟. 为保证测试结果真实可信,我们将JVM运行在 -server模式下,测试数据 ...