日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多项式——乘法逆元

發布時間:2024/1/1 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多项式——乘法逆元 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

多項式——乘法逆元

給定一個多項式 F(x)F(x)F(x) ,請求出一個多項式 G(x)G(x)G(x) 滿足 F(x)G(x)≡1modxnF(x)G(x) \equiv 1 \mod x^nF(x)G(x)1modxn 。系數對 998244353998244353998244353 取模。

P4238 【模板】多項式乘法逆

本文只介紹遞推的方法,首先將 nnn 補齊到 2 的冪次,當 n=1n = 1n=1 的時候,多項式中只有一項,那么 [x0]G(x)[x^0]G(x)[x0]G(x) 就是 [x0]F(x)[x^0]F(x)[x0]F(x) 的乘法逆元。

假設我們已知 F(x)H(x)≡1modxn2F(x)H(x) \equiv 1 \mod x^{\frac{n}{2}}F(x)H(x)1modx2n? ,那么顯然 F(x)G(x)≡1modxn2F(x) G(x) \equiv 1 \mod x^{\frac{n}{2}}F(x)G(x)1modx2n? ,那么 F(x)[G(x)?H(x)]≡0modxn2F(x)[G(x) - H(x)] \equiv 0 \mod x^{\frac{n}{2}}F(x)[G(x)?H(x)]0modx2n?,即 G(x)?H(x)≡0modxn2G(x) - H(x) \equiv 0 \mod x^{\frac{n}{2}}G(x)?H(x)0modx2n?

兩邊同時平方得到 G(x)2+H(x)2?2G(x)H(x)≡0modxnG(x)^2 + H(x)^2 -2G(x)H(x) \equiv 0 \mod x^nG(x)2+H(x)2?2G(x)H(x)0modxn ,這是因為原來是 xn2x^{\frac{n}{2}}x2n? 的倍數,平方之后一定也是 xnx^nxn 的 倍數。

最后,兩邊同時乘以 F(x)F(x)F(x) 使得 G(x)2G(x)^2G(x)2 項降冪,因為 F(x)G(x)≡1modxnF(x)G(x) \equiv 1 \mod x^nF(x)G(x)1modxn 最后得到:

G(x)≡2H(x)?F(x)H(x)2modxnG(x) \equiv 2H(x) - F(x)H(x)^2 \mod x^n G(x)2H(x)?F(x)H(x)2modxn

用 NTT 來加速多項式乘法,時間復雜度為 O(nlog?n)O(n \log n)O(nlogn)

#include <bits/stdc++.h>using namespace std;using ll = long long;#ifdef LLT_DBG #define FR freopen("in.txt", "r", stdin) #else #define FR #endiftemplate <ll P> ll fpow(ll a, ll b) {ll res = 1;for (; b; b >>= 1, a = (a * a) % P)if (b & 1)res = (res * a) % P;return res; }template <ll G, ll P> struct NTT {int _n;int E;vector<int> rev;/*** @brief 構建一個 NTT 計算器** @param n 多項式最高項數*/NTT(int n){_n = 1;E = 0;while (_n < n){_n <<= 1;E++;}rev.resize(_n);// 逆位置對換for (int i = 1; i < _n; i++){rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (E - 1));}}void _rNTT(ll A[], ll k){for (int i = 0; i < _n; i++)if (i < rev[i])swap(A[i], A[rev[i]]);for (int e = 1; e <= E; e++){int m = 1 << e;for (int i = 0; i < _n; i += m){int hf = m / 2;ll g = 1;ll gn = fpow<P>(fpow<P>(G, (P - 1) / m), k);for (int j = 0; j < hf; j++){ll x = A[i + j];ll y = (A[i + j + hf] * g) % P;A[i + j] = (x + y) % P;A[i + j + hf] = (x - y) % P;g = (g * gn) % P;}}}}/*** @brief NTT 過程** @param A 系數數組*/void doNTT(ll A[]){_rNTT(A, 1);}/*** @brief NTT 逆過程** @param A 點值數組*/void doINTT(ll A[]){ll ni = fpow<P>(_n, P - 2);_rNTT(A, P - 2);for (int i = 0; i < _n; i++)A[i] = (A[i] * ni) % P;} };ll A[500005]; ll F[500005]; ll B[500005]; ll G[500005];const int mod = 998244353;void solve() {int n;cin >> n;for (int i = 0; i < n; i++){cin >> A[i];}// 初始步驟G[0] = fpow<mod>(A[0], mod - 2);// 歸納步驟int i = 1;while (i < n){i <<= 1;for (int j = 0; j < i; j++)B[j] = 0;// 注意最大界為 2ifor (int j = 0; j < (i >> 1); j++)B[j] = G[j];for (int j = 0; j < i; j++)F[j] = A[j];NTT<3, mod> ntt(i << 1);ntt.doNTT(F);ntt.doNTT(B);for (int j = 0; j < (i << 1); j++)B[j] = B[j] * B[j] % mod * F[j] % mod;ntt.doINTT(B);for (int j = 0; j < i; j++){G[j] = (2 * G[j] % mod - B[j]) % mod;G[j] = (G[j] + mod) % mod;}}for (int i = 0; i < n; i++){G[i] = (G[i] + mod) % mod;cout << G[i] << " ";} }int main() {FR;solve();return 0; }

總結

以上是生活随笔為你收集整理的多项式——乘法逆元的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。