$\text{O}(n^2)$ 多项式运算

namespace Math{
  
#define MAXN 1001001
  
    int frac[MAXN],invf[MAXN],inv[MAXN];
  
    inline void init(int N){
        frac[0]=1;
        for(int i=1;i<=N;i++)
            frac[i]=1ll*frac[i-1]*i%mod;
        invf[N]=qpow(frac[N],mod-2);
        for(int i=N;i>=1;i--){
            invf[i-1]=1ll*invf[i]*i%mod;
            inv[i]=1ll*invf[i]*frac[i-1]%mod;
        }
    }
  
    inline long long C(int n,int m){
        return 1ll*frac[n]*invf[m]%mod*invf[n-m]%mod;
    }
  
#undef MAXN
  
}
  
using Math::frac;
using Math::invf;
using Math::inv;

template<int T>

struct Polyn{

    int n,a[T];

    Polyn(int _n=0){
        n=_n;
        for(int i=0;i<n;i++)a[i]=0;
    }

    int& operator [](const int x){
        return a[x];
    }

    inline Polyn R(){
        Polyn b(n);
        for(int i=0;i*2<n;i++)
            b[i]=a[n-1-i];
        return b;
    }
  
    inline Polyn Der(){
        Polyn b(n-1);
        for(int i=1;i<n;i++)
            b[i-1]=1ll*a[i]*i%mod;
        return b;
    }

    inline Polyn Int(){
        Polyn b(n+1);
        for(int i=1;i<=n;i++)
            b[i]=1ll*a[i-1]*inv[i]%mod;
        return b;
    }

    inline Polyn Inv(){
        Polyn b(n);
        b[0]=qpow(a[0],mod-2);
        long long inv=b[0];
        for(int i=1;i<n;i++){
            long long res=0;
            for(int j=0;j<i;j++)
                (res+=1ll*b[j]*a[i-j])%=mod;
            b[i]=(mod-res)*inv%mod;
        }
        return b;
    }

    Polyn operator -(){
        Polyn b(*this);
        for(int i=0;i<n;i++)
            b[i]=(mod-b[i])%mod;
        return b;
    }

    Polyn operator +(int x){
        Polyn b(*this);
        (b[0]+=x)%=mod;
        return b;
    }

    Polyn operator -(int x){
        Polyn b(*this);
        (b[0]+=mod-x)%=mod;
        return b;
    }

    Polyn operator *(int x){
        Polyn b(*this);
        for(int i=0;i<n;i++)
            b[i]=1ll*b[i]*x%mod;
        return b;
    }

    Polyn operator +(Polyn b){
        Polyn c=b;
        c.n=max(n,b.n);
        for(int i=b.n;i<c.n;i++)c[i]=0;
        for(int i=0;i<n;i++)
            (c[i]+=a[i])%=mod;
        return c;
    }

    Polyn operator -(Polyn b){
        Polyn c=(*this);
        c.n=max(n,b.n);
        for(int i=n;i<c.n;i++)c[i]=0;
        for(int i=0;i<b.n;i++)
            (c[i]+=mod-b[i])%=mod;
        return c;
    }

    Polyn operator *(Polyn b){
        Polyn c(n+b.n-1);
        for(int i=0;i<n;i++)
            for(int j=0;j<b.n;j++)
                (c[i+j]+=1ll*a[i]*b[j]%mod)%=mod;
        return c;
    }

    Polyn operator /(Polyn b){
        return (*this)*b.Inv();
    }

    Polyn operator %(Polyn b){
        Polyn r=(*this);
        for(int i=n-1;i>=b.n-1;i--){
            int inv=r[i]*qpow(b[b.n-1],mod-2);
            for(int j=i;j>=i-b.n+1;j--)
                (r[j]+=mod-1ll*b[j-i+b.n-1]*inv%mod)%=mod;
        }
        r.n=min(n,b.n-1);
        return r;
    }

    Polyn ln(){
        Polyn b(n);
        for(int i=1;i<n;i++){
            for(int j=1;j<i;j++)
                (b[i]+=1ll*b[j]*a[i-j]%mod*j%mod)%=mod;
            b[i]=(a[i]+mod-1ll*b[i]*inv[i]%mod)%mod;
        }
        return b;
    }

    Polyn exp(){
        Polyn b(n);
        b[0]=1;
        for(int i=1;i<n;i++){
            for(int j=1;j<=i;j++)
                (b[i]+=1ll*b[i-j]*a[j]%mod*j%mod)%=mod;
            b[i]=1ll*b[i]*inv[i]%mod;
        }
        return b;
    }

    inline int Y(int x){
        int Sum=0;
        for(int i=n-1;~i;i--)
            Sum=(1ll*Sum*x+a[i])%mod;
        return Sum;
    }

};
原文地址:https://www.cnblogs.com/wyzwyz/p/15549075.html