• 多项式全家桶递推版


    有的多项式题不需要用到 (O(nlog n)) 的多项式全家桶,所以来写下递推的 (O(n^2)) 做法。

    多项式求逆

    (B(x))(A(x)) 的逆,那么:

    [egin{aligned}B(x)A(x)&=[n==0]\sum_{i=0}^nA_iB_{n-i}&=0(n>0),B_0=frac{1}{A_0}(n=0)\B_n&=-frac{1}{A_0}sum_{i=1}^nA_iB_{n-i}end{aligned} ]

    Code

    void INV(int *a,int *ans,int n)
    {
        for (int i = 0;i <= n;i++)
            ans[i] = 0;
        ans[0] = mypow(a[0],p - 2);
        for (int i = 1;i <= n;i++)
        {
            for (int j = 1;j <= i;i++)
                ans[i] -= 1ll * a[j] * ans[i - j] % p,ans %= p;
            ans[i] = 1ll * ans[i] * ans[0] % p;
        }
    }
    

    多项式快速幂

    (B(x)=A^k(x)) ,那么:

    [egin{aligned}B'(x)&=kA'(x)A^{k-1}(x)\B'(x)A(x)&=kA'(x)B(x)\sum_{i=0}^nB'_iA_{n-i}&=ksum_{i=0}^nA'_iB_{n-i}\sum_{i=0}^nB_{i+1}(i+1)A_{n-i}&=ksum_{i=0}A_{i+1}(i+1)B_{n-i}\B_{n+1}=frac{k}{A_0(n+1)}&(sum_{i=0}^nA_{i+1}(i+1)B_{n-i}-sum_{i=0}^{n-1}B_{i+1}(i+1)A_{n-i})end{aligned} ]

    边界 (B_0=A_0^k)

    Code

    void Polypow(int *a,int *ans,int n,int k)
    {
        for (int i = 0;i <= n;i++)
            ans[i] = 0;
        int st = 0,sst = 0;
        while (!a[st])
            st++;
        sst = st;
        st = min(st * k - 1,n);
        if (st == n)
            return;
        st++;
        ans[st] = mypow(a[sst],k);
        int inv = mypow(a[sst],p - 2);
        for (int i = 1;i <= n - st;i++)
        {
            for (int j = 0;j < i;j++)
                ans[i + st] += 1ll * k * a[j + 1 + sst] % p * (j + 1) % p * ans[i - 1 - j + st] % p,ans[i + st] %= p;
            for (int j = 0;j < i - 1;j++)
                ans[i + st] -= 1ll * a[i - 1 - j + sst] * ans[j + 1 + st] % p * (j + 1) % p,ans[i + st] %= p;
            ans[i + st] = 1ll * ans[i + st] * inv % p * Inv[i] % p;
        }
    }
    

    Ln

    (B(x)=ln(A(x))) ,那么有 (B'(x)=frac{A'(x)}{A(x)}) ,那么:

    [egin{aligned}A'(x)&=B'(x)A(x)\A'_n&=sum_{i=0}^nA_iB'_{n-i}\A_{n+1}(n+1)&=sum_{i=0}^nA_iB_{n-i+1}(n-i+1)\B_{n+1}&=frac{1}{n+1}(A_{n+1}(n+1)-sum_{i=1}^nA_iB_{n-i+1}(n-i+1))end{aligned} ]

    要求 (A_0=1) ,边界 (B_0=0)

    Code

    void Ln(int *a,int *ans,int n)
    {
        for (int i = 0;i <= n;i++)
            ans[i] = 0;
        for (int i = 1;i <= n;i++)
        {
            ans[i] = 1ll * a[i] * i % p;
            for (int j = 1;j < i;j++)
                ans[i] -= 1ll * a[j] * ans[i - j] % p * (i - j) % p,ans[i] %= p;
            ans[i] = 1ll * ans[i] * Inv[i] % p;
        }
    }
    

    exp

    (B(x)=e^{A(x)}) ,那么:

    [egin{aligned}B'_n&=sum_{i=0}^nB_iA_{n-i}\B_{n+1}&=frac{1}{n+1}sum_{i=0}^nB_iA_{n-i+1}(n-i+1)end{aligned} ]

    要求 (A_0=0) ,边界 (B_0=1)

    Code

    void exp(int *a,int *ans,int n)
    {
        for (int i = 0;i <= n;i++)
            ans[i] = 0;
        ans[0] = 1;
        for (int i = 1;i <= n;i++)
        {
            for (int j = 0;j < i;j++)
                ans[i] += 1ll * ans[j] * a[i - j] % p * (i - j) % p,ans[i] %= p;
            ans[i] = 1ll * ans[i] * Inv[i] % p;
        }
    }
    

    kexp

    (B(x)=sum_{i=0}^kfrac{A^i(x)}{i!}) ,那么:

    [egin{aligned}B'(x)&=sum_{i=0}^kfrac{{A^i}'(x)}{i!}\B'(x)&=sum_{i=0}^kfrac{A^{i-1}(x)iA'(x)}{i!}\B'(x)&=A'(x)(B(x)-frac{A^k(x)}{k!})end{aligned} ]

    (C(x)=frac{A^k(x)}{k!}) ,可以通过多项式快速幂求出,然后就有:

    [egin{aligned}B'(x)&=A'(x)(B(x)-C(x))\B'_{n}&=sum_{i=0}^nA'_{i}(B_{n-i}-C_{n-i})\B_{n+1}&=frac{1}{n+1}sum_{i=0}^nA_{i+1}(i+1)(B_{n-i}-C(n-i))end{aligned} ]

    Code

    void kexp(int *a,int *ans,int n,int k)
    {
        int inv = 1,res = 1;
        for (int i = 1;i <= k;i++)
            inv = 1ll * inv * i % p;
        inv = mypow(inv,p - 2);
        Polypow(a,tmp,n,k);
        for (int i = 0;i <= n;i++)
            tmp[i] = 1ll * tmp[i] * inv % p;
        for (int i = 0;i <= n;i++)
            ans[i] = 0;
        ans[0] = 1;
        for (int i = 1;i <= k;i++)
        {
            res = 1ll * res * a[0] % p * Inv[i] % p;
            ans[0] += res;
            ans[0] %= p;
        }
        for (int i = 1;i <= n;i++)
        {
            for (int j = 0;j < i;j++)
                ans[i] += 1ll * a[j + 1] * (j + 1) % p * ((ans[i - j - 1] - tmp[i - j - 1]) % p) % p,ans[i] %= p;
            ans[i] = 1ll * ans[i] * Inv[i] % p;
        }
    }
    
  • 相关阅读:
    Chapter 4
    Chapter 3
    chapter 2
    Python编程指南 chapter 1
    BASE64 编码和解码
    生成 PDF 全攻略【2】在已有PDF上添加内容
    IDEA 和 Eclipse 使用对比
    web 前端常用组件【06】Upload 控件
    聊聊 Web 项目二维码生成的最佳姿势
    依附大系统 【数据实时获取】解决方案
  • 原文地址:https://www.cnblogs.com/sdlang/p/14299644.html
Copyright © 2020-2023  润新知