[洛谷P4726]【模板】多项式指数函数
題目大意:給出$n-1$次多項式$A(x)$,求一個 $\bmod{x^n}$下的多項式$B(x)$,滿足$B(x) \equiv e^{A(x)}$。
題解:(by Weng_weijie)
泰勒展開:
$$
f(x)=f(x_0)+\dfrac{f'(x_0)(x-x_0)}{1!}+\dfrac{f''(x_0)(x-x_0)^2}{2!}+\dots
$$
牛頓迭代:
$$
解關于 F(x) 的方程使得 G(F(x))\equiv 0\pmod{x^n} \\
假設 G(F_0(x)) \equiv 0 \pmod{x^{\big\lceil\dfrac{n}{2}\big\rceil}} \\
對 G(F(x)) 在 F_0(x) 處泰勒展開得 \\
G(F(x)) \equiv G(F_0(x)) + \dfrac{G'(F_0(x))(F(x)-F_0(x))}{1!}+\dots \pmod{x^n} \\
又F(x)-F_0(x)\equiv 0\pmod{x^{\big\lceil\dfrac{n}{2}\big\rceil}} \\
(F(x)-F_0(x))^2\equiv 0\pmod{x^n} \\
\begin{align*}
\therefore G(F(x))&\equiv G(F_0(x)) + G'(F_0(x))(F(x)-F_0(x))\\
&\equiv 0\pmod{x^n} \\
\end{align*}\\
得到 F(x)=F_0(x)-\dfrac{G(F_0(x))}{G'(F_0(x))}
$$
多項式指數函數:
$$
設F(x)=e^{A(x)}, \ln F(x)=A(x), G(F(x))=\ln F(x)-A(x) \\
于是就是解 G(F(x))=0,代入牛頓迭代公式得:\\
F(x)=F_0(x)(1-\ln F_0(x)+A(x))
$$
卡點:無
?
C++ Code:
#include <cstdio> #include <algorithm> #define maxn 1 << 18 | 3 const int mod = 998244353, G = 3; inline int pw(int base, int p) {int ans = 1;for (; p; p >>= 1, base = 1ll * base * base % mod) if (p & 1) ans = 1ll * ans * base % mod;return ans; } inline int Inv(int x) {return pw(x, mod - 2);} namespace Poly {int lim, ilim, s, rev[maxn];int Wn[maxn + 1], inv[maxn], __invnum;#define i __invnuminline int getinv(int n) {while (i < n) {i++; inv[i] = 1ll * inv[mod % i] * (mod - mod / i) % mod;}return inv[n];}inline void INIT() {inv[i = 1] = 1;}#undef iinline void init(int n) {lim = 1, s = -1; while (lim < n) lim <<= 1, s++; ilim = getinv(lim);for (int i = 0; i < lim; i++) rev[i] = rev[i >> 1] >> 1 | (i & 1) << s;int t = pw(G, (mod - 1) / lim);Wn[0] = 1; for (int i = 1; i <= lim; i++) Wn[i] = 1ll * Wn[i - 1] * t % mod;}inline void up(int &a, int b) {if ((a += b) >= mod) a -= mod;}inline void NTT(int *A, int op) {for (int i = 0; i < lim; i++) if (i < rev[i]) std::swap(A[i], A[rev[i]]);for (int mid = 1; mid < lim; mid <<= 1) {int t = lim / mid >> 1;for (int i = 0; i < lim; i += mid << 1) {for (int j = 0; j < mid; j++) {int W = op ? Wn[t * j] : Wn[lim - t * j];int X = A[i + j], Y = 1ll * A[i + j + mid] * W % mod;up(A[i + j], Y), up(A[i + j + mid] = X, mod - Y);}}}if (!op) for (int i = 0; i < lim; i++) A[i] = 1ll * A[i] * ilim % mod;}inline void DER(int *A, int *B, int n) {B[n - 1] = 0; for (int i = 1; i < n; i++) B[i - 1] = 1ll * A[i] * i % mod;}inline void INT(int *A, int *B, int n) {B[0] = 0; for (int i = 1; i < n; i++) B[i] = 1ll * A[i - 1] * inv[i] % mod;}int C[maxn];void INV(int *A, int *B, int n) {if (n == 1) {B[0] = Inv(A[0]); return ;}INV(A, B, n + 1 >> 1);init(n << 1);for (int i = 0; i < n; i++) C[i] = A[i];for (int i = n; i < lim; i++) C[i] = 0;NTT(B, 1), NTT(C, 1);for (int i = 0; i < lim; i++) B[i] = (2 + mod - 1ll * B[i] * C[i] % mod) * B[i] % mod;NTT(B, 0);for (int i = n; i < lim; i++) B[i] = 0;}int D[maxn];inline void LN(int *A, int *B, int n) {DER(A, D, n), INV(A, B, n);init(n << 1);NTT(B, 1), NTT(D, 1);for (int i = 0; i < lim; i++) D[i] = 1ll * D[i] * B[i] % mod;NTT(D, 0);INT(D, B, n);for (int i = n; i < lim; i++) B[i] = 0;} int E[maxn], F[maxn];void EXP(int *A, int *B, int n) {if (n == 1) {B[0] = 1; return ;}EXP(A, B, n + 1 >> 1);for (int i = 0; i < n << 1; i++) E[i] = F[i] = 0;LN(B, E, n);for (int i = 0; i < n; i++) F[i] = A[i];NTT(B, 1), NTT(E, 1), NTT(F, 1);for (int i = 0; i < lim; i++) B[i] = (1ll + mod - E[i] + F[i]) * B[i] % mod;NTT(B, 0);for (int i = n; i < lim; i++) B[i] = 0;} } int a[maxn], b[maxn], n; int main() {scanf("%d", &n);Poly::INIT();for (int i = 0; i < n; i++) scanf("%d", a + i);Poly::EXP(a, b, n);for (int i = 0; i < n; i++) printf("%d ", b[i]); puts("");return 0; }
轉載于:https://www.cnblogs.com/Memory-of-winter/p/9723954.html
總結
以上是生活随笔為你收集整理的[洛谷P4726]【模板】多项式指数函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++ 将输入存储到数组,然后反转数组,
- 下一篇: Kubernetes中的nodePort