BZOJ3684 大朋友和多叉树(多项式相关计算)
设$f(x)$为树的生成函数,即$x^i$的系数为根节点权值为$i$的树的个数。
不难得出$f(x)=\sum_{k\in D}f(x)^k+x$
我们要求这个多项式的第$n$项,由拉格朗日反演可得
$[x^n]f(x)=\frac1n[x^{n-1}](\frac x{g(x)})^n$
其中$[x^n]f(x)$表示$f(x)$的$n$次项系数。
$f(x)$是$g(x)$的复合逆,即$g(f(x))=x$
在本题中,$g(x)=x-\sum_{k\in D}x^k$
我们需要多项式求逆和多项式快速幂。
多项式求逆就不介绍了,多项式快速幂一种朴素的做法是倍增+NTT,复杂度是$O(n\log n\log k)$
有没有更快的做法呢?
观察到$f(x)^n=e^{n\ln(f(x))}$,所以我们只需要快速算$\ln(f(x))$及$e^{f(x)}$即可。
注意$f(x)$的常数项要为1,还好出题人良心保证了这一点。
Part 1:如何算$\ln(f(x))$?
设$g(x)=\ln(f(x))$,那么$g'(x)=\frac{f'(x)}{f(x)}$,所以$g(x)=\int\frac{f'(x)}{f(x)}$,时间复杂度$O(n\log n)$
Part 2:如何算$e^{f(x)}$?
还是考虑倍增,假设我已经求出$g_0(x)=e^{f(x)}(mod\;x^n)$,要求$g(x)=e^{f(x)}(mod\;x^{2n})$
根据泰勒展开,有$$0=h(g(x))=\sum_{i=0}^{\infty}\frac{h^{(i)}(g_0(x))}{i!}(g(x)-g_0(x))^i$$当$i>1$时,上式$mod\;x^{2n}$为$0$
所以$0=h(g_0(x))+h'(g_0(x))(g(x)-g_0(x))\;(mod\;x^{2n})$
即$g(x)=g_0(x)-\frac{h(g_0(x))}{h'(g_0(x))}(mod\;x^{2n})$
其中$h(g(x))=\ln(g(x))-f(x)$
所以$g(x)=g_0(x)-\frac{\ln(g_0(x))-f(x)}{\frac 1{g_0(x)}}=g_0(x)(1-\ln(g_0(x))+f(x))\;(mod\;x^{2n})$
时间复杂度$O(n\log n)$
#include <cstdio>
#include <cstring>
#include <algorithm>
#define pre m=n<<1; for(int i=0;i<m;i++) r[i]=(r[i>>1]>>1)|((i&1)<<l) typedef long long ll;
const int p=,N=;
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) {ll r=; for(;b;b>>=,a=a*a%p) if(b&) r=r*a%p; return r;} void ntt(int *a,int n,int f) {
for(int i=;i<n;i++) if(r[i]>i) std::swap(a[i],a[r[i]]);
for(int i=;i<n;i<<=)
for(int j=,wn=pw(,((p-)/(i*)*f+p-)%(p-));j<n;j+=i<<)
for(int k=,w=;k<i;k++,w=(ll)w*wn%p) {
int x=a[j+k],y=(ll)a[j+k+i]*w%p;
a[j+k]=(x+y)%p,a[j+k+i]=(x-y+p)%p;
}
if(!~f) for(int i=;i<n;i++) a[i]=(ll)a[i]*ni[n]%p;
}
void inv(int *f,int *g,int *t,int n,int l) {
if(n==) {g[]=pw(f[],p-); return;}
inv(f,g,t,n>>,l-),memcpy(t,f,sizeof(int)*n),memset(t+n,,sizeof(int)*n),pre;ntt(t,m,),ntt(g,m,);
for(int i=;i<m;i++) g[i]=(ll)g[i]*(-(ll)t[i]*g[i]%p+p)%p;
ntt(g,m,-),memset(g+n,,sizeof(int)*n);
}
void ln(int *f,int *g,int *t,int n,int l) {
memset(t,,sizeof(int)*n*),inv(f,t,t1,n,l);
for(int i=;i+<n;i++) g[i]=(ll)f[i+]*(i+)%p;
pre;ntt(g,m,),ntt(t,m,);
for(int i=;i<m;i++) g[i]=(ll)g[i]*t[i]%p;
ntt(g,m,-);
for(int i=m-;i;i--) g[i]=(ll)g[i-]*ni[i]%p;
g[]=,memset(g+n,,sizeof(int)*n);
}
void ex(int *f,int *g,int *t,int n,int l) {
if(n==) {g[]=; return;}
ex(f,g,t,n>>,l-),memset(t,,sizeof(int)*n*),ln(g,t,t2,n,l);
for(int i=;i<n;i++) t[i]=(f[i]-t[i]+p)%p;
t[]=(t[]+)%p,pre;ntt(t,m,),ntt(g,m,);
for(int i=;i<m;i++) g[i]=(ll)g[i]*t[i]%p;
ntt(g,m,-),memset(g+n,,sizeof(int)*n);
} int main() {
scanf("%d%d",&n,&m),f[]++,ni[]=,nn=n;
for(int i=;i<=m;i++) scanf("%d",&x),f[x-]=p-;
for(m=n,n=,l=;n<=m;n<<=) l++;
for(int i=;i<=n*;i++) ni[i]=(ll)(p-p/i)*ni[p%i]%p;
inv(f,g,t1,n,l),memset(f,,sizeof f),ln(g,f,t2,n,l);
for(int i=;i<n;i++) f[i]=(ll)f[i]*nn%p;
memset(g,,sizeof g),ex(f,g,t3,n,l),printf("%lld",(ll)g[nn-]*ni[nn]%p);
return ;
}
BZOJ3684 大朋友和多叉树(多项式相关计算)的更多相关文章
- bzoj3684: 大朋友和多叉树(拉格朗日反演+多项式全家桶)
题面 传送门 题解 首先你得知道什么是拉格朗日反演->这里 我们列出树的个数的生成函数 \[T(x)=x+\prod_{i\in D}T^i(x)\] \[T(x)-\prod_{i\in D} ...
- [BZOJ3684]大朋友和多叉树
设答案为$f_s$,它的生成函数为$\begin{align*}F(x)=\sum\limits_{i=0}^\infty f_ix^i\end{align*}$,则我们有$\begin{align* ...
- BZOJ 3684: 大朋友和多叉树 [拉格朗日反演 多项式k次幂 生成函数]
3684: 大朋友和多叉树 题意: 求有n个叶子结点,非叶节点的孩子数量\(\in S, a \notin S\)的有根树个数,无标号,孩子有序. 鏼鏼鏼! 树的OGF:\(T(x) = \sum_{ ...
- BZOJ 3684 大朋友和多叉树
BZOJ 3684 大朋友和多叉树 Description 我们的大朋友很喜欢计算机科学,而且尤其喜欢多叉树.对于一棵带有正整数点权的有根多叉树,如果它满足这样的性质,我们的大朋友就会将其称作神犇的: ...
- [BZOJ3684][拉格朗日反演+多项式求幂]大朋友和多叉树
题面 Description 我们的大朋友很喜欢计算机科学,而且尤其喜欢多叉树.对于一棵带有正整数点权的有根多叉树,如果它满足这样的性质,我们的大朋友就会将其称作神犇的:点权为\(1\)的结点是叶子结 ...
- 【bzoj3684】 大朋友和多叉树 生成函数+多项式快速幂+拉格朗日反演
这题一看就觉得是生成函数的题... 我们不妨去推下此题的生成函数,设生成函数为$F(x)$,则$[x^s]F(x)$即为答案. 根据题意,我们得到 $F(x)=x+\sum_{i∈D} F^i(x)$ ...
- 【BZOJ3684】大朋友和多叉树(拉格朗日反演)
题目链接 题意 求满足如下条件的多叉树个数: 1.每一个点的儿子个数在给定的集合 \(S\) 内 2.总的叶子节点树为 \(s\) 儿子之间有顺序关系,但节点是没有标号的. Sol 拉格朗日反演板子题 ...
- 【learning】多项式相关(求逆、开根、除法、取模)
(首先要%miskcoo,这位dalao写的博客(这里)实在是太强啦qwq大部分多项式相关的知识都是从这位dalao博客里面学的,下面这篇东西是自己对其博客学习后的一些总结和想法,大部分是按照其博客里 ...
- P2008 大朋友的数字
题目描述 有一批大朋友(年龄15岁以上),他们每人手上拿着一个数字,当然这个数字只有1位,也就是0到9之间.每个大朋友的分数为在他之前的最长不下降子序列中所有数之和.(这个序列必须以它作为结尾!)如有 ...
随机推荐
- 亚马逊AWS学习——EC2的自定义VPC配置
1 网络配置 EC2即亚马逊AWS云服务中的虚拟主机.创建EC2实例时如果使用的默认VPC并分配了公有IP是可以上网的.但我们经常需要自定义的网络环境,这时就需要自己定义VPC和子网了. 1.1 配置 ...
- 从一次输入框无法输入的bug,谈如何限制输入框输入类型
bug的产生和修改 上周临近周末休息的时候,一个同事跑过来了,对我说:"阿伦啊,有一个页面出问题了,火狐浏览器所有的input都没法输入了."我一听,是不是你给加了什么属性,让in ...
- 接触JS的变量
刚刚接触到js,写的代码都是很简单的,制单的概念也相当少,新学习的就是变量.let和const以及js的数据类型. 变量的内容有五个,我就不一一介绍了,重点在于: 在 JavaScript 中,使用变 ...
- Python之旅.第四章.模块与包.总结(未完待遇)
一.模块 模块: 一系列功能的集合体,在python中一个py文件就是一个模块,模块名就是py文件的文件名: 模块的好处: 1.减少重复的代码 2.拿来主义 定义模块: 就是创建一个py文件: 使用模 ...
- SpringBoot的RestController vs @ResponseBody + @Controller
@Controller和@RestController的区别?官方文档:@RestController is a stereotype annotation that combines @Respon ...
- groovy入门(2-1)Groovy的Maven插件安装:Plugin execution not covered by lifecycle configuration
参考链接:http://www.cnblogs.com/rightmin/p/4945797.html 1.引入groovy的jar包 2.引入groovy编译插件 3.遇到问题 Plugin exe ...
- Tomcat8.0 配置环境
(1)首先安装JDk 下载jdk进行安装后进行配置环境 新增一个Java_Home的变量复制本地安装目录的路径:eg:C:\Program Files (x86)\Java\jdk1.8.0_141\ ...
- leetcode算法:Reshape the Matrix
In MATLAB, there is a very useful function called 'reshape', which can reshape a matrix into a new o ...
- 人工智能算法综述(二) RNN and LSTM
接上一篇 :AI算法综述 (一) RNN:循环神经网络 and LSTM 长短期记忆网络 LSTM就是一个RNN网络,外部的结构是一样的,主要是单元的内在结构不同.或者说LSTM是为了让RNN能够更好 ...
- Python scrapy框架
Scrapy Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 )所设 ...