bzoj3684: 大朋友和多叉树(拉格朗日反演+多项式全家桶)
题面
题解
首先你得知道什么是拉格朗日反演->这里
我们列出树的个数的生成函数
\]
\]
我们记\(F(x)=T(x)\),\(G(x)=x-\prod_{i\in D}x^i\),那么有\(G(F(x))=x\)
根据拉格朗日反演,可得
\]
//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=5e5+5,P=950009857,g=7,Gi=135715694;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
return res;
}
int r[N],O[N],F[N],G[N],inv[N],lim,l,n,m;
void init(R int len){
lim=1,l=0;while(lim<len)lim<<=1,++l;
fp(i,0,lim-1)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
}
void NTT(int *A,int ty){
fp(i,0,lim-1)if(i<r[i])swap(A[i],A[r[i]]);
for(R int mid=1;mid<lim;mid<<=1){
int I=(mid<<1),Wn=ksm(ty==1?g:Gi,(P-1)/I);O[0]=1;
fp(i,1,mid-1)O[i]=mul(O[i-1],Wn);
for(R int j=0;j<lim;j+=I)fp(k,0,mid-1){
int x=A[j+k],y=mul(O[k],A[j+k+mid]);
A[j+k]=add(x,y),A[j+k+mid]=dec(x,y);
}
}
if(ty==-1)for(R int i=0,inv=ksm(lim,P-2);i<lim;++i)A[i]=mul(A[i],inv);
}
void Inv(int *a,int *b,int len){
if(len==1)return b[0]=ksm(a[0],P-2),void();
Inv(a,b,len>>1);static int A[N],B[N];init(len<<1);
fp(i,0,len-1)A[i]=a[i],B[i]=b[i];
fp(i,len,lim-1)A[i]=B[i]=0;
NTT(A,1),NTT(B,1);
fp(i,0,lim-1)A[i]=mul(A[i],mul(B[i],B[i]));
NTT(A,-1);
fp(i,0,len-1)b[i]=dec(add(b[i],b[i]),A[i]);
fp(i,len,lim-1)b[i]=0;
}
void Ln(int *a,int *b,int len){
static int A[N],B[N];
fp(i,1,len-1)A[i-1]=mul(a[i],i);A[len-1]=0;
Inv(a,B,len),init(len<<1);
fp(i,len,lim-1)A[i]=B[i]=0;
NTT(A,1),NTT(B,1);
fp(i,0,lim-1)A[i]=mul(A[i],B[i]);
NTT(A,-1);
fp(i,1,len-1)b[i]=mul(A[i-1],inv[i]);b[0]=0;
fp(i,len,lim-1)b[i]=0;
}
void Exp(int *a,int *b,int len){
if(len==1)return b[0]=1,void();
Exp(a,b,len>>1);static int A[N];
Ln(b,A,len),init(len<<1);
A[0]=dec(a[0]+1,A[0]);
fp(i,1,len-1)A[i]=dec(a[i],A[i]);
fp(i,len,lim-1)A[i]=b[i]=0;
NTT(A,1),NTT(b,1);
fp(i,0,lim-1)b[i]=mul(b[i],A[i]);
NTT(b,-1);
fp(i,len,lim-1)b[i]=0;
}
void ksm(int *a,int *b,int len,int k){
static int A[N];
Ln(a,A,len);
fp(i,0,len-1)A[i]=mul(A[i],k);
Exp(A,b,len);
}
int Lagrange(int *a,int len,int k){
static int A[N],B[N];
Inv(a,A,len),ksm(A,B,len,k);
return mul(B[k-1],inv[k]);
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read();
int len=1;while(len<=n)len<<=1;
inv[0]=inv[1]=1;fp(i,2,len)inv[i]=1ll*(P-P/i)*inv[P%i]%P;
++F[0];while(m--)--F[read()-1];
printf("%d\n",Lagrange(F,len,n));
return 0;
}
bzoj3684: 大朋友和多叉树(拉格朗日反演+多项式全家桶)的更多相关文章
- BZOJ 3684: 大朋友和多叉树 [拉格朗日反演 多项式k次幂 生成函数]
3684: 大朋友和多叉树 题意: 求有n个叶子结点,非叶节点的孩子数量\(\in S, a \notin S\)的有根树个数,无标号,孩子有序. 鏼鏼鏼! 树的OGF:\(T(x) = \sum_{ ...
- 【BZOJ3684】大朋友和多叉树(拉格朗日反演)
题目链接 题意 求满足如下条件的多叉树个数: 1.每一个点的儿子个数在给定的集合 \(S\) 内 2.总的叶子节点树为 \(s\) 儿子之间有顺序关系,但节点是没有标号的. Sol 拉格朗日反演板子题 ...
- loj#6363. 「地底蔷薇」(拉格朗日反演+多项式全家桶)
题面 传送门 题解 肝了一个下午--我老是忘了拉格朗日反演计算的时候多项式要除以一个\(x\)--结果看它推倒简直一脸懵逼-- 做这题首先你得知道拉格朗日反演是个什么东西->这里 请坐稳,接下来 ...
- [BZOJ3684]大朋友和多叉树
设答案为$f_s$,它的生成函数为$\begin{align*}F(x)=\sum\limits_{i=0}^\infty f_ix^i\end{align*}$,则我们有$\begin{align* ...
- BZOJ3684 大朋友和多叉树(多项式相关计算)
设$f(x)$为树的生成函数,即$x^i$的系数为根节点权值为$i$的树的个数.不难得出$f(x)=\sum_{k\in D}f(x)^k+x$我们要求这个多项式的第$n$项,由拉格朗日反演可得$[x ...
- [BZOJ3684][拉格朗日反演+多项式求幂]大朋友和多叉树
题面 Description 我们的大朋友很喜欢计算机科学,而且尤其喜欢多叉树.对于一棵带有正整数点权的有根多叉树,如果它满足这样的性质,我们的大朋友就会将其称作神犇的:点权为\(1\)的结点是叶子结 ...
- BZOJ 3684 大朋友和多叉树
BZOJ 3684 大朋友和多叉树 Description 我们的大朋友很喜欢计算机科学,而且尤其喜欢多叉树.对于一棵带有正整数点权的有根多叉树,如果它满足这样的性质,我们的大朋友就会将其称作神犇的: ...
- 【bzoj3684】 大朋友和多叉树 生成函数+多项式快速幂+拉格朗日反演
这题一看就觉得是生成函数的题... 我们不妨去推下此题的生成函数,设生成函数为$F(x)$,则$[x^s]F(x)$即为答案. 根据题意,我们得到 $F(x)=x+\sum_{i∈D} F^i(x)$ ...
- [拉格朗日反演][FFT][NTT][多项式大全]详解
1.多项式的两种表示法 1.系数表示法 我们最常用的多项式表示法就是系数表示法,一个次数界为\(n\)的多项式\(S(x)\)可以用一个向量\(s=(s_0,s_1,s_2,\cdots,s_n-1) ...
随机推荐
- 往jdk/bin目录中增加tcnative-1.dll文件以后报错 Can't load AMD 64-bit .dll on a IA 32-bit platform
开始时,运行Tomcat控制台报错: The APR based Apache Tomcat Native library which allows optimal performance in pr ...
- 2015.3.3 VC6调用dll
用VC新建一对话框工程,在一按钮点击事件中添加如下代码: typedef void (WINAPI * TESTDLL)(); HINSTANCE hmod; hmod = ::LoadLibrary ...
- php字符型转整型
$arr = array(0=>1,"aa"=>2, 3, 4); foreach($arr as $key=>$val){ print($key == &quo ...
- vue中父子组件传递信息实现
为了能够在父子组件中实现双向控制,需要以下的步骤: 第一步:子组件中挖坑 (1)在需要父组件填充具体内容的地方挖坑,方式为 <slot name="message">& ...
- 初识DDD
DDD强调专注于业务问题域的需要:其专业术语.为何开发该软件的关键原因,以及对于业务来说什么才是成功 问题域涉及你当前正在构建软件的主题领域 DDD强调的是,在致力于为大型复杂业务系统创建软件时,专注 ...
- Spring MVC F5刷新问题
转自:https://bbs.csdn.net/topics/390771056 post操作成功后重定向到B,这样浏览器里F5的时候就不会让提交A了
- nginx注册成服务
http://blog.csdn.net/t37240/article/details/51727563
- MySQL存储引擎 -- MyISAM 与 InnoDB 理论对比
MySQL常用的两种存储引擎一个是MyISAM,另一个是InnoDB.两种存储引擎各有各的特点. 1. 区别:(1)事务处理:MyISAM是非事务安全型的.-----而非事务型的系统,一般也称为数据仓 ...
- SpringMVC_04 拦截器 【拦截器的编程步骤】【session复习?】
待更新... 2017年5月13日22:45:31 1 什么是拦截器 spring提供的一个特殊组件,前端控制器 DispacherServlet 在收到请求之后,会先调用拦截器,再调用处理器(Co ...
- 简单的jQuery前端验证码校验
简单的jQuery前端验证码校验2 html; <!DOCTYPE html> <html lang="zh-cn"> <head> <m ...