版权声明:既然是蒟蒻写的文,那么各位大爷就将就着看吧~ https://blog.csdn.net/alan_cty/article/details/81914993
Description
我们的大朋友很喜欢计算机科学,而且尤其喜欢多叉树。对于一棵带有正整数点权的有根多叉树,如果它满足这样的性质,我们的大朋友就会将其称作神犇的:点权为1的结点是叶子结点;对于任一点权大于1的结点u,u的孩子数目deg[u]属于集合D,且u的点权等于这些孩子结点的点权之和。
给出一个整数s,你能求出根节点权值为s的神犇多叉树的个数吗?请参照样例以更好的理解什么样的两棵多叉树会被视为不同的。
我们只需要知道答案关于950009857(453*2^21+1,一个质数)取模后的值。
m,s<=100000
Solution
样例告诉我们儿子是有顺序的
设F(x)为答案的生成函数,那么我们有
考虑写成复合逆的形式,
把F(x)用x替换,设左边的生成函数为G(x),那么F(x)和G(x)互为复合逆
拉格朗日反演:
发现右边x/G(x)的常数项是1,于是我们可以用求ln再求exp的方式来做快速幂
然后就写多项式全家桶喽
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
const int N=4e5+5,Mo=950009857;
int pwr(int x,int y) {
int z=1;
for(;y;y>>=1,x=(ll)x*x%Mo)
if (y&1) z=(ll)z*x%Mo;
return z;
}
ll t[N],W[N];
void DFT(ll *a,int len,int flag) {
int lg=0;for(;(1<<lg)<len;lg++);
W[0]=1;W[1]=pwr(7,(Mo-1)/len);
fo(i,2,len) W[i]=W[i-1]*W[1]%Mo;
for(int i=0;i<len;i++) {
int p=0;
for(int j=i,k=0;k<lg;k++,j>>=1) p=(p<<1)+(j&1);
t[p]=a[i];
}
for(int m=2;m<=len;m<<=1) {
int half=m/2,times=len/m;
for(int i=0;i<half;i++) {
ll w=(flag>0)?W[i*times]:W[len-i*times];
for(int j=i;j<len;j+=m) {
ll u=t[j],v=t[j+half]*w;
t[j]=(u+v)%Mo;t[j+half]=(u-v)%Mo;
}
}
}
for(int i=0;i<len;i++) a[i]=t[i];
if (flag==-1) {
int inv=pwr(len,Mo-2);
for(int i=0;i<len;i++) a[i]=a[i]*inv%Mo;
}
}
ll c[N];
void get_Inv(ll *a,ll *b,int n) {
if (n==1) {b[0]=pwr(a[0],Mo-2);return;}
get_Inv(a,b,n>>1);
int len=n<<1;
fo(i,0,n-1) c[i]=a[i];fo(i,n,len-1) c[i]=0;
fo(i,(n>>1),len-1) b[i]=0;
DFT(c,len,1);DFT(b,len,1);
fo(i,0,len-1) b[i]=(2*b[i]-b[i]*b[i]%Mo*c[i])%Mo;
DFT(b,len,-1);
fo(i,n,len-1) b[i]=0;
}
ll f[N],g[N];
void get_ln(ll *a,ll *b,int n) {
fo(i,0,n-2) f[i]=a[i+1]*(i+1)%Mo;f[n-1]=0;
get_Inv(a,g,n);
int len=n<<1;
fo(i,n,len-1) f[i]=g[i]=0;
DFT(f,len,1);DFT(g,len,1);
fo(i,0,len-1) f[i]=f[i]*g[i]%Mo;
DFT(f,len,-1);
fo(i,1,n-1) b[i]=f[i-1]*pwr(i,Mo-2)%Mo;
b[0]=0;
}
ll h[N];
void get_exp(ll *a,ll *b,int n) {
if (n==1) {b[0]=1;return;}
get_exp(a,b,n>>1);
get_ln(b,h,n);
fo(i,0,n-1) h[i]=(a[i]-h[i]+Mo)%Mo;
(h[0]=h[0]+1)%=Mo;
int len=n<<1;
fo(i,n,len-1) h[i]=b[i]=0;
DFT(h,len,1);DFT(b,len,1);
fo(i,0,len-1) b[i]=b[i]*h[i]%Mo;
DFT(b,len,-1);
fo(i,n,len-1) b[i]=0;
}
ll H[N];
void get_pow(ll *a,int n,int m) {
get_ln(a,H,n);
fo(i,0,n-1) H[i]=H[i]*m%Mo;
get_exp(H,a,n);
}
int n,m,x,len;
ll F[N],G[N];
int main() {
scanf("%d%d",&n,&m);
for(len=1;len<=n;len<<=1);
fo(i,1,m) {
scanf("%d",&x);
G[x-1]--;
}
G[0]++;
get_Inv(G,F,len);
get_pow(F,len,n);
ll ans=F[n-1]*pwr(n,Mo-2)%Mo;
printf("%lld\n",(ans+Mo)%Mo);
return 0;
}