# 多项式求导

## 原理

$A(x) = \sum_{i = 0}^{n} c_i x^i$

$A'(x) = \sum_{i = 1}^{n} ic_ix^{i - 1}$

## 实现

void Der(int *f, int *g, int lf) {
For (i, 1, lf) g[i - 1] = 1ll * i * f[i] % Mod; g[lf] = 0;
}


# 多项式积分

## 原理

$A(x) = \sum_{i = 0}^{n} c_i x^i$

$\int A(x) \mathrm{d} x = \sum_{i = 1}^{n + 1} \frac{c_{i - 1}}{i} x^{i}$

## 实现

void Int(int *f, int *g, int lf) {
g[0] = 0;
For (i, 1, lf + 1)
g[i] = 1ll * f[i - 1] * inv[i] % Mod;
}


# 多项式乘法

## 实现

int rev[Maxn], W[Maxn], len;
void NTT(int *P, int opt) {
Rep (i, len) if (i < rev[i]) swap(P[i], P[rev[i]]);
for (int i = 2, p; p = i >> 1, i <= len; i <<= 1) {
W[0] = 1; W[1] = fpm(~opt ? g : invg, (Mod - 1) / i);
For (k, 2, p - 1) W[k] = 1ll * W[k - 1] * W[1] % Mod;
for (int j = 0; j < len; j += i) Rep (k, p) {
int u = P[j + k], v = 1ll * P[j + k + p] * W[k] % Mod;
P[j + k] = (u + v) % Mod; P[j + k + p] = (u - v + Mod) % Mod;
}
}
if (!~opt) {
int invn = fpm(len, Mod - 2);
Rep (i, len) P[i] = 1ll * P[i] * invn % Mod;
}
}

void Prepare(int lc) {
int cnt = -1; for (len = 1; len <= lc; len <<= 1) ++ cnt;
Rep (i, len) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << cnt);
}

int A[Maxn], B[Maxn], C[Maxn];
void Mult(int *a, int *b, int *c, int la, int lb) {
int lc = la + lb; Prepare(lc);
Rep (i, len) A[i] = i <= la ? a[i] : 0; NTT(A, 1);
Rep (i, len) B[i] = i <= lb ? b[i] : 0; NTT(B, 1);
Rep (i, len) C[i] = 1ll * A[i] * B[i] % Mod; NTT(C, -1);
For (i, 0, lc) c[i] = C[i];
}


# 多项式牛顿迭代

## 原理

$$\pmod x$$ 时，可以求出 $$A(x)$$ 的常数项。

$$\bmod {x^{2n}}$$ 下，在 $$A(x)$$ 处展开 $$f(B(x))$$

$f(B(x)) = \sum_{i \ge 0} \frac{f^{(i)}(A(x))}{i!}(B(x) - A(x))^i$

\begin{aligned} f(B(x)) &\equiv f(A(x)) + f'(A(x))(B(x) - A(x)) &\pmod {x^{2n}}\\ B(x) &\equiv A(x) - \frac{f(A(x))}{f'(A(x))} &\pmod {x^{2n}} \end{aligned}

# 多项式求逆

## 原理

$$F(x)$$$$P(x)$$$$\pmod {x^n}$$ 下的逆元，那么表示出来就是

$F(x)P(x) \equiv 1 \pmod {x^n}$

$$n = 1$$ 求逆元即可，假设我们求出在 $$\bmod x^{\frac n 2}$$ 意义下的逆元 $$G(x)$$ ，那么有

$G(x)P(x) \equiv 1 \pmod {x^\frac n 2}\\$

\begin{aligned} F(x) - G(x) &\equiv 0 \pmod {x^\frac n 2}\\ F^2(x) - 2F(x)G(x) + G^2(x) &\equiv 0 \pmod {x^n}\\ F(x) &\equiv 2G(x) - P(x)G^2(x) \pmod {x^n} \end{aligned}

## 实现

void Inv(int *f, int *g, int lf) {
if (lf == 1) return void(g[0] = fpm(f[0], Mod - 2));
Inv(f, g, lf >> 1); Prepare(lf << 1);
Rep (i, len) A[i] = i < lf ? f[i] : 0; NTT(A, 1);
Rep (i, len) B[i] = i < lf ? g[i] : 0; NTT(B, 1);
Rep (i, len) C[i] = 1ll * A[i] * B[i] % Mod * B[i] % Mod; NTT(C, -1);
Rep (i, lf) g[i] = (g[i] * 2ll + Mod - C[i]) % Mod;
}


# 多项式开根

## 原理

$$F^2(x) \equiv P(x) \pmod {x^n}$$ ，此时的 $$f(A(x)) = A^2 - P$$ 我们要求它的零点。

\begin{aligned} B(x) &= A(x) - \frac{A^2(x) - P(x)}{2A(x)}\\ &= \frac{A(x)}2 + \frac{P(x)}{2A(x)} \end{aligned}

## 实现

void Sqrt(int *f, int *g, int lf) {
if (lf == 1) return void(g[0] = getsqrt(f[0]));
Sqrt(f, g, lf >> 1); static int tmp[Maxn], tinv[Maxn];
Rep (i, lf) tmp[i] = 2 * g[i] % Mod; Inv(tmp, tinv, lf);
Mult(f, tinv, tmp, lf, lf);
const int inv2 = fpm(2, Mod - 2);
Rep (i, lf) g[i] = (1ll * g[i] * inv2 % Mod + tmp[i]) % Mod;
}


# 多项式ln

## 原理

$$G(x) = \ln F(x)$$ ，我们有

$G(x) = \int \frac{F'(x)}{F(x)} \mathrm{d}x$

## 实现

void Ln(int *f, int *g, int lf) {
static int der[Maxn], tmp[Maxn];
Der(f, der, lf); Inv(f, tmp, lf);
Mult(der, tmp, tmp, lf, lf); Int(tmp, g, lf);
}


# 多项式exp

## 原理

\begin{aligned} B(x) &= \exp(A(x))\\ B'(x) &= A'(x) \exp(A(x))\\ B'(x) &= A'(x) B(x)\\ B(x) &= \int A'(x)B(x) \mathrm{d}x \end{aligned}

## 实现

void Exp(int *a, int *b, int l, int r) {
if (l == r) return void(b[l] = (l ? 1ll * b[l] * inv[l] % Mod : 1));
int mid = (l + r) >> 1;
Exp(a, b, l, mid); static int tmp[Maxn];
Mult(a, b + l, tmp, r - l, mid - l);
For (i, mid + 1, r) b[i] = (b[i] + tmp[i - l - 1]) % Mod;
Exp(a, b, mid + 1, r);
}

void Exp(int *f, int *g, int lf) {
static int der[Maxn];
Der(f, der, lf); der[lf] = 0;
memset(g, 0, sizeof(int) * (lf + 1));
Exp(der, g, 0, lf);
}


# 多项式快速幂

## 原理

$$G(x) = F^k(x)$$ ，我们取对数有 $$\ln G(x) = k \ln F(x)$$ 也就是 $$G(x) = \exp(k \ln F(x))$$

## 代码

void Pow(int *f, int *g, int lf, int power) {
static int tf[Maxn], tmp[Maxn], invf; assert(f[0]);

invf = fpm(f[0], Mod - 2);
Rep (i, lf) tf[i] = 1ll * f[i] * invf % Mod;

Ln(tf, tmp, lf); Rep (i, lf) tmp[i] = 1ll * tmp[i] * power % Mod; Exp(tmp, g, lf);

invf = fpm(fpm(invf, Mod - 2), power);
Rep (i, lf) g[i] = 1ll * g[i] * invf % Mod;
}


# 多项式复合逆

## 原理

$$G(F(x)) = x$$$$F(x)$$ 的一项。此时 $$G(x)$$ 可能是和 $$F$$ 同阶的一个多项式，套用牛顿迭代项数会特别多，根本无法求解。

$[x^n] F(x) = \frac 1n [x^{n - 1}] (\frac{x}{G(x)})^n$

## 实现

int Lagrange(int *f, int lf, int x) {
static int tmp[Maxn], res[Maxn];
Rep (i, lf) res[i] = f[i + 1]; Inv(res, tmp, lf); Power(tmp, res, n);
return 1ll * res[x - 1] * fpm(x, Mod - 2) % Mod;
}

posted @ 2019-06-02 18:10  zjp_shadow  阅读(867)  评论(0编辑  收藏  举报