首页 > 其他分享 >【学习笔记】多项式学习笔记3:全家桶科技

【学习笔记】多项式学习笔记3:全家桶科技

时间:2023-02-11 15:13:57浏览次数:39  
标签:int 多项式 笔记 学习 pmod Poly dfrac equiv

点击查看目录

目录

参考资料:OI-Wiki

多项式求导与积分

\[(ax^n)'=a\times nx^{n-1} \]

\[\int ax^n=\dfrac{a}{n+1}x^{n+1} \]

单独对每一项操作后加和。

预处理逆元,时间复杂度 \(O(n)\)。

inline Poly Differential(int L){
    Poly F;
    F.set(L);
    for(int i=1;i<L;++i) F[i-1]=1ll*i*f[i]%mod;
    return F;
}
inline Poly Integral(int L){
    Poly F;
    F.set(L+1);
    for(int i=0;i<L;++i) F[i+1]=1ll*inv[i+1]*f[i]%mod;
    return F;
}

多项式牛顿迭代

牛顿强啊!

设函数 \(G\),要求一多项式 \(f(x)\),满足:

\[G(f(x))\equiv 0\pmod {x^n} \]

假定已经求得 \(f_0(x)\),满足:

\[G(f_0(x))\equiv 0\pmod {x^{\left\lceil n/2\right\rceil}} \]

泰勒展开:

\[G(f(x))=\sum_{i=0}^{\infty} \dfrac{G^{(i)}(f_0(x))}{i!}(f(x)-f_0(x))^i \]

由于右侧 \(f(x)-f_0(x)\) 的最低非零次项次数为 \(\left\lceil n/2\right\rceil\),因此:

\[\forall i\ge 2,(f(x)-f_0(x))^i\equiv 0\pmod {x^n} \]

于是式子实际上是:

\[G(f_0(x))+G'(f_0(x))(f(x)-f_0(x))\equiv 0\pmod {x^n} \]

整理一下就是:

\[f(x)\equiv f_0(x)-\dfrac{G(f_0(x))}{G'(f_0(x))}\pmod {x^n} \]

于是我们只需要求出 \([x^0]f(x)\) 再倍增即可。

多项式求逆

给定 \(F(x)\),求 \(G(x)\) 使得:

\[F(x)G(x)\equiv 1\pmod {x^n} \]

常规倍增法

假设已经求得 \(G_0\) 满足:

\[F(x)G_0(x)\equiv 1\pmod {x^{\left\lceil n/2\right\rceil}} \]

接下来推一下式子:

\[\begin{aligned} G(x)&\equiv G_0(x)&\pmod {x^{\left\lceil n/2\right\rceil}}\\ G(x)-G_0(x)&\equiv 0&\pmod {x^{\left\lceil n/2\right\rceil}}\\ (G(x)-G_0(x))^2&\equiv 0&\pmod {x^n}\\ F(x)(G^2(x)-2G(x)G_0(x)+G_0^2(x))&\equiv 0&\pmod {x^n}\\ G(x)-2G_0(x)+F(x)G_0^2(x)&\equiv 0&\pmod {x^n}\\ \end{aligned}\]

于是得到:

\[G(x)\equiv G_0(x)(2-F(x)G_0(x))\pmod {x^n} \]

牛顿迭代法

构造:

\[G(f(x))=\dfrac{1}{f(x)}-F(x) \]

代入牛顿迭代式:

\[f(x)=f_0(x)-\dfrac{\dfrac{1}{f_0(x)}-F(x)}{-\dfrac{1}{f_0^2(x)}} \]

整理一下就是:

\[f(x)\equiv f_0(x)(2-F(x)f_0(x))\pmod {x^n} \]

inline Poly Inv(int n){
    Poly F,G;
    F.set(4*n),G.set(4*n);
    G[0]=q_pow(f[0],mod-2,mod);
    for(int L=2;L<2*n;L<<=1){
        F.set(2*L),G.set(2*L);
        F.clear(0,2*L-1);
        for(int i=0;i<L;++i) F[i]=f[i];
        F.NTT(2*L,1),G.NTT(2*L,1);
        for(int i=0;i<2*L;++i){
            G[i]=1ll*G[i]*(2ll-1ll*F[i]*G[i]%mod+mod)%mod;
        }
        G.NTT(2*L,0);
        G.clear(min(n,L),2*L-1);
    }
    return G;
}

多项式开根

给定 \(F(x)\),求 \(G(x)\) 使得:

\[F(x)\equiv G^2(x)\pmod {x^n} \]

常规倍增法

假设已经求得 \(G_0\) 满足:

\[F(x)\equiv G_0^2(x)\pmod {x^{\left\lceil n/2\right\rceil}} \]

接下来推一下式子:

\[\begin{aligned} G(x)&\equiv G_0(x)&\pmod {x^{\left\lceil n/2\right\rceil}}\\ G(x)-G_0(x)&\equiv 0&\pmod {x^{\left\lceil n/2\right\rceil}}\\ (G(x)-G_0(x))^2&\equiv 0&\pmod {x^n}\\ G^2(x)-2G(x)G_0(x)+G_0^2(x)&\equiv 0&\pmod {x^n}\\ F(x)-2G(x)G_0(x)+G_0^2(x)&\equiv 0&\pmod {x^n}\\ \end{aligned}\]

于是得到:

\[G(x)\equiv \dfrac{F(x)+G_0^2(x)}{2G_0(x)}\pmod {x^n} \]

即:

\[G(x)\equiv \dfrac{F(x)}{2G_0(x)}+\dfrac{G_0(x)}{2}\pmod {x^n} \]

牛顿迭代法

构造:

\[G(f(x))=f^2(x)-F(x) \]

代入牛顿迭代式:

\[f(x)=f_0(x)-\dfrac{f_0^2(x)-F(x)}{2f_0(x)} \]

整理一下就是:

\[f(x)\equiv \dfrac{F(x)+f_0^2(x)}{2f_0(x)}\pmod {x^n} \]

即:

\[f(x)\equiv \dfrac{F(x)}{2f_0(x)}+\dfrac{f_0(x)}{2}\pmod {x^n} \]

inline Poly Sqrt(int n){
    Poly F,G,invG,H;
    F.set(4*n),G.set(4*n);
    G[0]=1;
    for(int L=2;L<2*n;L<<=1){
        F.set(2*L),G.set(2*L),H.set(2*L);
        F.clear(0,2*L-1);
        for(int i=0;i<L;++i) F[i]=f[i];
        invG=G.Inv(L);
        F.NTT(2*L,1),invG.NTT(2*L,1);
        for(int i=0;i<2*L;++i) H[i]=1ll*F[i]*invG[i]%mod*inv_2%mod;
        H.NTT(2*L,0);
        for(int i=0;i<2*L;++i) G[i]=(H[i]+1ll*G[i]*inv_2%mod+mod)%mod;
        G.clear(min(n,L),2*L-1);
    }
    return G;
}

多项式对数函数

给定 \(F(x)\),求 \(G(x)\) 使得:

\[\ln F(x)\equiv G(x)\pmod {x^n} \]

左侧相当于一个复合函数,对左右求导:

\[(\ln F(x))'\times F'(x)\equiv G'(x)\pmod {x^n} \]

根据简单初等函数的导数得:

\[\dfrac{F'(x)}{F(x)}\equiv G'(x)\pmod {x^n} \]

求出 \(G'(x)\) 后积分得到 \(G(x)\):

\[G(x)=\int G'(x) \mathrm{d}x \]

inline Poly Ln(int n){
    Poly dF,invF,G,H;
    dF=Differential(n),invF=Inv(n);
    int L=1;
    while(L<2*n) L<<=1;
    dF.set(L),invF.set(L),G.set(L);
    dF.NTT(L,1),invF.NTT(L,1);
    for(int i=0;i<L;++i) G[i]=1ll*dF[i]*invF[i]%mod;
    G.NTT(L,0);
    H=G.Integral(L);
    H.clear(n,L-1);
    return H;
}

多项式指数函数

给定 \(F(x)\),求 \(G(x)\) 使得:

\[\exp F(x)\equiv G(x)\pmod {x^n} \]

使用牛顿迭代法,构造:

\[G(f(x))=\ln f(x)-F(x) \]

代入牛顿迭代式:

\[f(x)=f_0(x)-\dfrac{\ln f_0(x)-F(x)}{\dfrac{1}{f_0(x)}} \]

整理一下就是:

\[f(x)\equiv f_0(x)(1-\ln f_0(x)+F(x))\pmod {x^n} \]

inline Poly Exp(int n){
    Poly F,G,lnG;
    G.set(4*n),lnG.set(4*n);
    G[0]=1;
    for(int L=2;L<2*n;L<<=1){
        F.set(2*L),G.set(2*L),lnG.set(2*L);
        F.clear(0,2*L-1);
        for(int i=0;i<L;++i) F[i]=f[i];
        lnG=G.Ln(L);
        F.NTT(2*L,1),G.NTT(2*L,1),lnG.NTT(2*L,1);
        for(int i=0;i<2*L;++i) G[i]=1ll*G[i]*(1ll-lnG[i]+F[i]+mod)%mod;
        G.NTT(2*L,0);
        G.clear(min(n,L),2*L-1);
    }
    return G;
}

多项式半家桶封装模板

点击查看代码
int rev[maxn];
int base,w[maxn];
int inv[maxn];
struct Poly{
    const static int g=3;
    const static int inv_g=332748118;
    const static int inv_2=499122177;
    int deg;
    vector<int> f;
    int& operator[](const int& i){return f[i];}
    int operator[](const int& i)const{return f[i];}
    inline void set(int L){deg=L,f.resize(L);}
    inline void clear(int L,int R){for(int i=L;i<=R;++i)f[i]=0;}
    inline void output(int L){for(int i=0;i<L;++i)printf("%d ",f[i]);printf("\n");}
    inline Poly Differential(int L){
        Poly F;
        F.set(L);
        for(int i=1;i<L;++i) F[i-1]=1ll*i*f[i]%mod;
        return F;
    }
    inline Poly Integral(int L){
        Poly F;
        F.set(L+1);
        for(int i=0;i<L;++i) F[i+1]=1ll*inv[i+1]*f[i]%mod;
        return F;
    }
    inline void NTT(int L,bool type){
        set(L);
        for(int i=1;i<L;++i){
            rev[i]=(rev[i>>1]>>1)+(i&1?L>>1:0);
            if(i<rev[i]) swap(f[i],f[rev[i]]);
        }
        for(int d=1;d<L;d<<=1){
            base=q_pow(type?g:inv_g,(mod-1)/(2*d),mod);
            w[0]=1;
            for(int i=1;i<d;++i) w[i]=1ll*w[i-1]*base%mod;
            for(int i=0;i<L;i+=d<<1){
                for(int j=0;j<d;++j){
                    int x=f[i+j],y=1ll*w[j]*f[i+d+j]%mod;
                    f[i+j]=(x+y)%mod,f[i+d+j]=(x-y+mod)%mod;
                }
            }
        }
        if(!type){
            int inv_L=q_pow(L,mod-2,mod);
            for(int i=0;i<L;++i) f[i]=1ll*inv_L*f[i]%mod;
        }
    }
    inline Poly Inv(int n){
        Poly F,G;
        F.set(4*n),G.set(4*n);
        G[0]=q_pow(f[0],mod-2,mod);
        for(int L=2;L<2*n;L<<=1){
            F.set(2*L),G.set(2*L);
            F.clear(0,2*L-1);
            for(int i=0;i<L;++i) F[i]=f[i];
            F.NTT(2*L,1),G.NTT(2*L,1);
            for(int i=0;i<2*L;++i){
                G[i]=1ll*G[i]*(2ll-1ll*F[i]*G[i]%mod+mod)%mod;
            }
            G.NTT(2*L,0);
            G.clear(min(n,L),2*L-1);
        }
        return G;
    }
    inline Poly Sqrt(int n){
        Poly F,G,invG,H;
        F.set(4*n),G.set(4*n);
        G[0]=1;
        for(int L=2;L<2*n;L<<=1){
            F.set(2*L),G.set(2*L),H.set(2*L);
            F.clear(0,2*L-1);
            for(int i=0;i<L;++i) F[i]=f[i];
            invG=G.Inv(L);
            F.NTT(2*L,1),invG.NTT(2*L,1);
            for(int i=0;i<2*L;++i) H[i]=1ll*F[i]*invG[i]%mod*inv_2%mod;
            H.NTT(2*L,0);
            for(int i=0;i<2*L;++i) G[i]=(H[i]+1ll*G[i]*inv_2%mod+mod)%mod;
            G.clear(min(n,L),2*L-1);
        }
        return G;
    }
    inline Poly Ln(int n){
        Poly dF,invF,G,H;
        dF=Differential(n),invF=Inv(n);
        int L=1;
        while(L<2*n) L<<=1;
        dF.set(L),invF.set(L),G.set(L);
        dF.NTT(L,1),invF.NTT(L,1);
        for(int i=0;i<L;++i) G[i]=1ll*dF[i]*invF[i]%mod;
        G.NTT(L,0);
        H=G.Integral(L);
        H.clear(n,L-1);
        return H;
    }
    inline Poly Exp(int n){
        Poly F,G,lnG;
        G.set(4*n),lnG.set(4*n);
        G[0]=1;
        for(int L=2;L<2*n;L<<=1){
            F.set(2*L),G.set(2*L),lnG.set(2*L);
            F.clear(0,2*L-1);
            for(int i=0;i<L;++i) F[i]=f[i];
            lnG=G.Ln(L);
            F.NTT(2*L,1),G.NTT(2*L,1),lnG.NTT(2*L,1);
            for(int i=0;i<2*L;++i) G[i]=1ll*G[i]*(1ll-lnG[i]+F[i]+mod)%mod;
            G.NTT(2*L,0);
            G.clear(min(n,L),2*L-1);
        }
        return G;
    }
}F,G;

标签:int,多项式,笔记,学习,pmod,Poly,dfrac,equiv
From: https://www.cnblogs.com/SoyTony/p/Learning_Notes_about_Polynomial_3.html