首页 > 其他 > 详细

拉格朗日反演

时间:2019-02-19 13:34:53      阅读:197      评论:0      收藏:0      [点我收藏+]

1.幂级数的复合

对于幂级数\(F(x)\)\(G(x)\),我们称\(F(G(x))\)为幂级数F和G的复合

2.复合逆:

如果\(F(x)\)\(G(x)\)满足\(F(G(x))=G(F(x))=x\)则称它们互为复合逆

3.拉格朗日反演:

如果\(F(x)\)\(G(x)\)互为复合逆,则有\([x^n]G(x)=\frac1n[x^{n-1}](\frac{1}{F(x)/x})^n\)

可以通过这个在\(O(n\log n)\)(多项式exp和ln求快速幂,巨大常数)或\(O(n\log^2n)\)(倍增快速幂,小常数)来求复合逆的某一项(如果求整个复合逆的最优复杂度为\(O(n^2)\)的大步小步思想)

一下为多项式倍增快速幂取模和拉格朗日反演的板子,可以配合ghj1222的多项式板子食用

void poly_qpow(int *a, int len, int n)
{
    int *tmp = new int[len * 2];
    for (int i = 0; i < len * 2; i++) tmp[i] = i >= len ? 0 : a[i], a[i] = (i == 0);
    while (n > 0)
    {
        ntt(tmp, len * 2, 1);
        if (n & 1)
        {
            ntt(a, len * 2, 1);
            for (int i = 0; i < len * 2; i++) a[i] = a[i] * (long long)tmp[i] % p;
            ntt(a, len * 2, -1);
            for (int i = len; i < len * 2; i++) a[i] = 0;
        }
        for (int i = 0; i < len * 2; i++) tmp[i] = tmp[i] * (long long)tmp[i] % p;
        ntt(tmp, len * 2, -1);
        for (int i = len; i < len * 2; i++) tmp[i] = 0;
        n >>= 1;
    }
    delete []tmp;
}

int lagrange_inversion(int *aa, int len, int n)
{
    int *a = new int[len * 2];
    for (int i = 0; i < len; i++) a[i] = aa[i];
    for (int i = len; i < len * 2; i++) a[i] = 0;
    for (int i = 1; i < len; i++) a[i - 1] = a[i];
    poly_inv(a, len);
    poly_qpow(a, len, n);
    int ans = a[n - 1] * (long long)qpow(n, p - 2) % p;
    delete []a;
    return ans;
}

拉格朗日反演

原文:https://www.cnblogs.com/oier/p/10400448.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!