题面

Description

我们的大朋友很喜欢计算机科学,而且尤其喜欢多叉树。对于一棵带有正整数点权的有根多叉树,如果它满足这样的性质,我们的大朋友就会将其称作神犇的:点权为\(1\)的结点是叶子结点;对于任一点权大于\(1\)的结点\(u\),\(u\)的孩子数目\(deg_u\)属于集合\(D\),且\(u\)的点权等于这些孩子结点的点权之和。

给出一个整数\(s\),你能求出根节点权值为\(s\)的神犇多叉树的个数吗?请参照样例以更好的理解什么样的两棵多叉树会被视为不同的。

我们只需要知道答案关于\(950009857\)(\(453\times2^{21}+1\),一个质数)取模后的值。

Input

第一行有\(2\)个整数\(s,m\)。

第二行有\(m\)个互异的整数,\(d_1,d_2,\ldots,d_m\),为集合\(D\)中的元素。

Output

输出一行仅一个整数,表示答案模\(950009857\)的值。

Sample Input

4 2

2 3

Sample Output

10

HINT



\(1\le m\le s\le10^5,2\le d_i\le s\),有\(3\)组小数据和\(3\)组大数据。

分析

首先,我们设\(v_i\)为集合\(D\)中是否有\(i\)这个元素,有则为\(1\),无则为\(0\):$$v_i=\sum_{k=1}^{m}[d_k=i]$$

我们令\(V(x)\)为\(v_i\)的生成函数:$$V(x)=\sum_{k=0}^\infty v_i x^k$$

我们再设\(f_i\)为根节点权值为\(i\)的神犇多叉树的数量。

首先,显然有\(f_0=0\);而当\(i=1\)即叶子节点时,有\(f_1=1\)。

而在\(i>1\)时,我们枚举根节点的儿子节点数量,在枚举各个叶子节点的权值,根据乘法原理得到递归式:$$f_i=\sum_{k=0}{i-1}v_k\sum_{s_1+s_2+\cdots+s_k=i};;\prod_{j=1}k f_j$$

我们发现后面这个是一个\(k\)重卷积。那么我们令\(F(x)\)为\(f_i\)的生成函数:$$F(x)=\sum_{k=0}^\infty f_k x^k$$

那么我们根据递归式再加上特殊情况时的值,可以得到:$$F(x)=\sum_{k=0}^\infty v_k F(x)^k+x$$

那么我们发现这就是\(V(x)\)的形式。那么我们就得到:$$F(x)=V(F(x))+x$$

即$$F(x)-V(F(x))=x$$

只要我们令\(G(x)=x-V(x)\),就可以构造出一个拉格朗日反演的形式:$$G(F(x))=x$$

那么我们作反演就得到:$$[xn]F(x)=\frac{1}{n}[x{n-1}]\left(\frac{x}{G(x)}\right)^n$$

即:$$f_s=\frac{1}{s}[x{s-1}]\left(\frac{x}{G(x)}\right)s$$

注意到我们可以\(x\)和\(G(x)\)约掉一个\(x\),则我们令:$$H(x)=\sum_{k=0}^\infty v_{k+1} x^k=\frac{C(x)}{x}$$

则有:$$f_s=\frac{1}{s}[x{s-1}]\left(\frac{1}{1-H(x)}\right)n$$

我们直接多项式求逆+多项式求幂就可以解决了。

关于拉格朗日反演、多项式的操作,详见我的这篇博客:多项式全家桶

代码

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long ll;
const ll p=950009857,g=7;
int n,nn,s,m,r[262145];
ll inv[262145],c[262145],gn[2][262145],ans;
inline ll pow(ll a,int b){
ll ans=1;
while(b){
if(b&1)ans=ans*a%p;
a=a*a%p;
b>>=1;
}
return ans;
}
inline ll add(ll a,ll b){return a+b>p?a+b-p:a+b;}
inline ll cut(ll a,ll b){return a-b<0?a-b+p:a-b;}
void init(){
for(n=1;n<=s;n<<=1);
nn=n;
gn[0][0]=gn[1][0]=1;
gn[0][1]=pow(g,(p-1)/(n<<1));
gn[1][1]=pow(gn[0][1],p-2);
for(int i=2;i<(n<<1);i++){gn[0][i]=gn[0][i-1]*gn[0][1]%p;gn[1][i]=gn[1][i-1]*gn[1][1]%p;}
inv[1]=1;
for(int i=2;i<=(n<<1);i++)inv[i]=inv[p%i]*(p-p/i)%p;
}
void NTT(ll c[],int n,int tp=1){
for(int i=0;i<n;i++){
r[i]=(r[i>>1]>>1)|((i&1)*(n>>1));
if(i<r[i])swap(c[i],c[r[i]]);
}
for(int i=1;i<n;i<<=1){
for(int j=0;j<n;j+=(i<<1)){
for(int k=0;k<i;k++){
ll x=c[j+k],y=gn[tp!=1][nn/i*k]*c[j+k+i]%p;
c[j+k]=add(x,y);
c[j+k+i]=cut(x,y);
}
}
}
}
void INTT(ll c[],int n){
NTT(c,n,-1);
for(int i=0;i<n;i++)c[i]=c[i]*inv[n]%p;
}
void inverse(ll c[],int n=n){
static ll t[262145],tma[262145];
t[0]=pow(c[0],p-2);
for(int k=2;k<=n;k<<=1){
for(int i=0;i<(k<<1);i++)tma[i]=(i<k?c[i]:0);
for(int i=(k>>1);i<(k<<1);i++)t[i]=0;
NTT(tma,k<<1);
NTT(t,k<<1);
for(int i=0;i<(k<<1);i++)t[i]=cut(add(t[i],t[i]),t[i]*t[i]%p*tma[i]%p);
INTT(t,k<<1);
}
memcpy(c,t,sizeof(ll)*n);
}
void derivative(ll c[],int n=n){for(int i=0;i<n;i++)c[i]=c[i+1]*(i+1)%p;}
void integrate(ll c[],int n=n){for(int i=n-1;i>=1;i--)c[i]=c[i-1]*inv[i]%p;c[0]=0;}
void ln(ll c[],int n=n){
static ll t[262145];
for(int i=0;i<(n<<1);i++)t[i]=(i<n?c[i]:0);
derivative(t,n);
inverse(c,n);
NTT(t,n<<1);
NTT(c,n<<1);
for(int i=0;i<(n<<1);i++)c[i]=c[i]*t[i]%p;
INTT(c,n<<1);
for(int i=n;i<(n<<1);i++)c[i]=0;
integrate(c,n);
}
void exp(ll c[]){
static ll t[262145],ta[262145];
t[0]=1;
for(int k=2;k<=n;k<<=1){
for(int i=0;i<(k<<1);i++)ta[i]=t[i];
ln(ta,k);
for(int i=0;i<k;i++)ta[i]=cut(c[i],ta[i]);
ta[0]++;
NTT(t,k<<1);
NTT(ta,k<<1);
for(int i=0;i<(k<<1);i++)t[i]=t[i]*ta[i]%p;
INTT(t,k<<1);
for(int i=k;i<(k<<1);i++)t[i]=0;
}
memcpy(c,t,sizeof(ll)*n);
}
void pow(ll c[],int k){
ln(c);
for(int i=0;i<n;i++)c[i]=c[i]*k%p;
exp(c);
}
int main(){
scanf("%d%d",&s,&m);
for(int i=1;i<=m;i++){
int x;
scanf("%d",&x);
c[x-1]=p-1;
}
c[0]=1;
init();
inverse(c);
pow(c,s);
printf("%lld\n",c[s-1]*inv[s]%p);
}

[BZOJ3684][拉格朗日反演+多项式求幂]大朋友和多叉树的更多相关文章

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

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

  2. BZOJ 3684 大朋友和多叉树

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

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

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

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

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

  5. 【BZOJ3684】大朋友和多叉树(拉格朗日反演)

    题目链接 题意 求满足如下条件的多叉树个数: 1.每一个点的儿子个数在给定的集合 \(S\) 内 2.总的叶子节点树为 \(s\) 儿子之间有顺序关系,但节点是没有标号的. Sol 拉格朗日反演板子题 ...

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

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

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

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

  8. loj#6363. 「地底蔷薇」(拉格朗日反演+多项式全家桶)

    题面 传送门 题解 肝了一个下午--我老是忘了拉格朗日反演计算的时候多项式要除以一个\(x\)--结果看它推倒简直一脸懵逼-- 做这题首先你得知道拉格朗日反演是个什么东西->这里 请坐稳,接下来 ...

  9. 【Weiss】【第03章】练习3.8:有序多项式求幂

    [练习3.8] 编写一个程序,输入一个多项式F(X),计算出(F(X))P.你程序的时间复杂度是多少? Answer: (特例:P==0时,返回1.) 如果P是偶数,那么就递归计算((F(X))P/2 ...

随机推荐

  1. P1736 创意吃鱼法80

    题目描述 回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*).她发现,把大池子视为01矩阵(0表示对应位置无鱼,1 ...

  2. Java并发基础:线程的创建

    线程的创建和管理: 1.应用Thread类显式创建.管理线程 2.应用Executor创建并管理线程. 定义任务: 无返回的任务:实现Runnable接口并编写run()方法. 有响应的任务:实现Ca ...

  3. kickstart2019 round_C B. Circuit Board

    思路: 这题应该不止一种解法,其中的一种可以看作是leetcode85https://www.cnblogs.com/wangyiming/p/11059176.html的加强版: 首先对于每一行,分 ...

  4. Team Foundation 版本控制

    与 Visual Studio 的一流集成. 使用富文件和文件夹差异工具突出显示代码更改. 借助强大的可视化跨分支跟踪代码更改. 集成的代码评审工具有助于在签入代码之前获得反馈. 使用托管版本或本地版 ...

  5. TestNG并发测试包

    https://www.yiibai.com/testng/basic-annotations.html

  6. pat甲级1044二分查找

    1044 Shopping in Mars(25 分) Shopping in Mars is quite a different experience. The Mars people pay by ...

  7. java Vamei快速教程08 继承

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 继承(inheritance)是面向对象的重要概念.继承是除组合(composit ...

  8. TFS看板的迭代规划

    故事点 故事点更多体现的是用户情景或者bug的规模,采用斐波拉契数列(1,2,3,5,8,13)这样的数字表示,包含如下内容: 相对工作量 复杂度 风险和不确定性 相对工作量 下面演示一个Case来说 ...

  9. 用virtualenv构建一个新的python环境,这个新的环境在这个创建的文件夹下

    http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143271210830032 ...

  10. python_14_sys_mod

    import sys #1 print(sys.path)#打印环境变量 #2 print(sys.argv)#打印相对路径 print(sys.argv[2])#在cmd命令窗口运行本文件