[BZOJ3684]大朋友与多叉树

题面

拉反板子题。

拉格朗日反演

对于多项式 \(F(x)\),若存在多项式满足 \(G(F(x))=x\) ,则称 $G(x) $ 为 \(F(x)\) 的复合逆,同时也有 \(F(G(x))=x\) 不会证明

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

其中\(F,G\)的常数项均为零 ,且一次项均不为零

证明?

\(F(x)=\sum_{i=0}f_{i}x^i\)

那么有:

\[\begin{aligned} F(G(x))=\sum_{i=0}f_{i}G^i(x)&=x\\ \end{aligned} \]

两边同时求导,

\[\begin{aligned} \sum_{i=0}if_{i}G^{i-1}(x)G'(x)&=1\\ [x^{-1}]\sum_{i=0}if_{i}G^{i-n-1}(x)G'(x)&=[x^{-1}]\frac{1}{G^n(x)}\\ \end{aligned} \]

这里取负数次是对的,证明不会

可以发现 \(G^{i-n-1}(x)G'(x)=\frac{1}{i-n}(G^{i-n}(x))'\)

分类讨论:

  1. \(i\not=n\)

    那么此时 \(i-n<0\) ,那么\([x^{-1}](G^{i-n}(x))'=[x^{0}]G^{i-n}(x)=0\),没有贡献。

  2. \(i=n\)

    \[\begin{aligned} &[x^{-1}]nf_{n}\frac{G'(x)}{G(x)}\\ &=nf_{n}[x^{-1}]\frac{g_{1}+2g_{2}x+\dots}{g_{1}x+g_{2}x^{2}+\dots}\\ &=nf_{n}[x^{-1}]\frac{g_{1}+2g_{2}x+\dots}{g_{1}x}\frac{1}{1+\frac{g_{2}}{g_1}x+\frac{g_{3}}{g_1}x^2+\dots}\\ \end{aligned} \]

    注意到左边式子的最低项为 \(x^{-1}\) ,系数为 \(1\) ,而右边式子求逆之后的最低项是常数项,系数为 \(1\)

    所以原式\(=nf_{n}\)

    所以也就有 \(nf_{n}=[x^{-1}]\frac{1}{G^{n}(x)}\)

可是右边那玩意又有\([x^{-1}]\)\(G(x)\) 也没有逆,怎么办?

分子分母同乘 \(x^{n}\) ,有 \(f_{n}=\frac{1}{n}[x^{n-1}]\frac{x^{n}}{G^{n}(x)}=\frac{1}{n}[x^{n-1}]\frac{1}{(\frac{G(x)}{x})^{n}}\)

证明完毕。

题解

考虑到树的生成函数形式 \(F(x)=x+\sum_{i\in D}F^{i}(x)\)

也就是有 \(F(x)-\sum_{i\in D} F^i(x)=x\)

那么也就是说 $G(x)=x-\sum_{i\in D} x^i $ 是 \(F(x)\) 的复合逆。

根据 \(F(x)[x^n]=\frac{1}{n}[x^{n-1}]\frac{1}{(\frac{G(x)}{x})^n}\),已经可以推出答案了。

Code
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
#define ll long long
#define ui unsigned int
il ll read(){
    bool f=true;ll x=0;
    register char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=false;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    if(f) return x;
    return ~(--x);
}
il void write(const ll &x){if(x>9) write(x/10);putchar(x%10+'0');}
il void print(const ll &x) {x<0?putchar('-'),write(~(x-1)):write(x);putchar('\n');}
il ll max(const ll &a,const ll &b){return a>b?a:b;}
il ll min(const ll &a,const ll &b){return a<b?a:b;}
namespace Poly{
    const ll mod=950009857;
    ll ksm(ll d,ll t){
        ll res=1;
        for(;t;t>>=1){
            if(t&1) res=res*d%mod;
            d=d*d%mod;
        }
        return res;
    }
    il ll dec(ll x,ll y) {return x>=y?x-y:x-y+mod;}
    il ll add(ll x,ll y) {return x+y<mod?x+y:x+y-mod;}
    const int N=262144<<1;
    vector<ll> w[23];
    ll fac[N],ifac[N],inv[N];
    il ll C(ll x,ll y){
        if(x<y) return 0;
        return fac[x]*ifac[y]%mod*ifac[x-y]%mod;
    }
    void init(){
        int n=N-1;
        fac[0]=1;
        for(ri i=1;i<=n;++i) fac[i]=i*fac[i-1]%mod;
        ifac[n]=ksm(fac[n],mod-2);
        for(ri i=n-1;~i;--i) ifac[i]=ifac[i+1]*(i+1)%mod;
        for(ri i=n;i;--i) inv[i]=ifac[i]*fac[i-1]%mod;
        inv[0]=1;
        int d=log(N)/log(2)+0.5;
        for(ri i=1;i<=d;++i){
            w[i].resize(1<<i);
            w[i][0]=1,w[i][1]=ksm(7,(mod-1)>>i);
            for(ri j=2;j<(1<<i);++j) w[i][j]=w[i][j-1]*w[i][1]%mod;
        }
    }
    int r[N];
    void DFT(int limit,ll *a,int flag){
        for(ri i=1;i<limit;++i) if(r[i]<i) swap(a[i],a[r[i]]);
        for(ri l=1,t=1;l<limit;l<<=1,++t){
            for(ri i=0;i<limit;i+=l<<1){
                ll *W=&w[t][0];
                for(ri j=0;j<l;++j){
                    ll tmp=a[i+j+l]*(*W++)%mod;
                    a[i+j+l]=dec(a[i+j],tmp);
                    a[i+j]=add(a[i+j],tmp);
                }
            }
        }
        if(flag==-1){
            reverse(a+1,a+limit);
            ll inv=ksm(limit,mod-2);
            for(ri i=0;i<limit;++i) a[i]=a[i]*inv%mod;
        }
    }
    ll _F[N];
    void rev(int limit,int ws){
        for(ri i=0;i<limit;i+=2){
            r[i]=r[i>>1]>>1;
            r[i|1]=(r[i>>1]>>1)|(1<<ws-1);
        }
    }
    void NTT(int n,ll *f,int m,ll *g,int lim=0){
        if(!lim) lim=n+m;
        int limit=1,ws=0;
        for(;limit<=n+m;++ws,limit<<=1);
        rev(limit,ws);
        for(ri i=0;i<=m;++i) _F[i]=g[i];
        for(ri i=m+1;i<limit;++i) _F[i]=0;
        for(ri i=n+1;i<limit;++i) f[i]=0;
        DFT(limit,f,1),DFT(limit,_F,1);
        for(ri i=0;i<limit;++i) f[i]=f[i]*_F[i]%mod;
        DFT(limit,f,-1);
        for(ri i=lim+1;i<limit;++i) f[i]=0;
    }
    void Inv(int n,ll *h,ll *f){
        memset(_F,0,sizeof(_F));
        f[0]=ksm(h[0],mod-2);
        for(ri t=1,l=2;1;l<<=1,++t){
            for(ri i=0;i<l;++i) _F[i]=h[i];
            rev(l<<1,t+1);
            DFT(l<<1,f,1),DFT(l<<1,_F,1);
            for(ri i=0;i<(l<<1);++i) f[i]=(2*f[i]-f[i]*f[i]%mod*_F[i]%mod+mod)%mod;
            DFT(l<<1,f,-1);
            if(l>n){
                for(ri i=n+1;i<(l<<1);++i) f[i]=0;
                break;
            }
            for(ri i=l;i<(l<<1);++i) f[i]=0;
        }
    }
    il void der(int n,ll *f){
        for(ri i=0;i<n;++i) 
            f[i]=f[i+1]*(i+1)%mod;
        f[n]=0;
    }
    il void Int(int n,ll *f){
        for(ri i=n;i;--i) 
            f[i]=f[i-1]*inv[i]%mod;
        f[0]=0;
    }
    ll _G[N];
    il void Ln(int n,ll *h,ll *f){
        memset(_G,0,sizeof(_G));
        for(ri i=0;i<=n;++i) f[i]=h[i];
        Inv(n,h,_G);
        der(n,f);
        NTT(n,f,n,_G);
        Int(n,f);
    }
    ll exp_f[N];
    il void exp(int n,ll *h,ll *f){
        f[0]=1;
        for(ri l=2,t=1;1;l<<=1,t++){
            memset(exp_f,0,sizeof(exp_f));
            Ln(l-1,f,exp_f);
            for(ri i=0;i<l;++i) exp_f[i]=(-exp_f[i]+h[i]+mod)%mod;
            exp_f[0]++;
            NTT(l>>1,f,l,exp_f);
            for(ri i=l;i<(l<<1);++i) f[i]=0;
            if(l>n){
                for(ri i=n+1;i<l;++i) f[i]=0;
                break;
            }
        }
    }
    ll ksm_f[N];
    il void polyksm(int n,ll *f,ll t){
        memset(ksm_f,0,sizeof(ksm_f));
        for(ri i=0;i<=n;++i) ksm_f[i]=f[i];
        Ln(n,ksm_f,f);
        for(ri i=0;i<=n;++i) ksm_f[i]=f[i]*t%mod,f[i]=0;
        exp(n,ksm_f,f);
    }
    il void div(int n,ll *f,int m,ll *g,ll *Q,ll *R){
        reverse(f,f+n+1),reverse(g,g+m+1);
        Inv(n-m,g,Q),NTT(n-m,Q,n-m,f,n-m);
        reverse(f,f+n+1),reverse(g,g+m+1),reverse(Q,Q+n-m+1);
        for(ri i=0;i<=m;++i) R[i]=g[i];NTT(m,R,n-m,Q);
        for(ri i=0;i<=n;++i) R[i]=dec(f[i],R[i]);
    }
}
using namespace Poly;
ll G[N],s,m,F[N];
int main(){
    // freopen("rand.in","r",stdin);
    // freopen("1.out","w",stdout);
    init();
    s=read(),m=read();
    G[0]=1;
    for(ri i=1;i<=m;++i) G[read()-1]=mod-1;
    polyksm(s,G,s);
    Inv(s,G,F);
    print(inv[s]*F[s-1]%mod);
    return 0;
}
posted @ 2021-08-24 11:35  krimson  阅读(46)  评论(0编辑  收藏  举报