拉格朗日反演
阿新 • • 發佈:2019-02-19
delete inline amp pre grang mat 最優 復雜 pow 的大步小步思想)
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; }
拉格朗日反演