多項式求逆
前置知識:ntt
給定乙個多項式 \(f\left(x\right)\),求乙個多項式 \(g\left(x\right)\),使得 \(f\left(x\right)g\left(x\right)\equiv 1\left(\bmod 998244353\right)\)。
考慮遞迴求解。
假定現在已經求出了 \(g_0\left(x\right)\),滿足
\[f\left(x\right)g_0\left(x\right)\equiv 1\left(\bmod x^\rceil}\right)\tag 1
\]根據要求的 \(g\left(x\right)\) 的定義,顯然有
\[f\left(x\right)g\left(x\right) \equiv 1\left(\bmod x^\rceil}\right)\tag 2
\]\((2) - (1)\),得
\[f\left(x\right)\left(g\left(x\right) - g_0\left(x\right)\right) \equiv 0 \left(\bmod x^\rceil}\right)
\]因為 \(f\left(x\right) \not\equiv 0\left(\bmod x^\rceil}\right)\),所以有
\[g\left(x\right) - g_0\left(x\right) \equiv 0 \left(\bmod x^\rceil}\right)
\]兩邊平方,得
\[g^2\left(x\right) - 2g\left(x\right)g_0\left(x\right) + g_0^2\left(x\right) \equiv 0\left(\bmod x^n\right)
\]兩邊同乘 \(f\left(x\right)\),得
\[g\left(x\right) - 2g_0\left(x\right) + f\left(x\right)g_0^2\left(x\right) \equiv 0\left(\bmod x^n\right)
\]移項整理
\[g\left(x\right) \equiv 2g_0\left(x\right) - f\left(x\right)g_0^2\left(x\right) \left(\bmod x^n\right)
\]遞迴處理之後自下而上遞推即可。
**:
int rev[maxn];
void setrev(int len)
}void ntt(ll p, int len, int type)
} }if(type == 1)
}ll tmp[maxn];
void polyinv(ll a, ll b, int siz)
polyinv(a, b, (siz + 1) >> 1);
int len = 1, l = (siz << 1); while(l) l >>= 1, len <<= 1;
for(int i = 0; i < siz; ++i) tmp[i] = a[i];
for(int i = siz; i < len; ++i) tmp[i] = 0;
setrev(len); ntt(tmp, len, 0); ntt(b, len, 0);
for(int i = 0; i < len; ++i) b[i] = ((2ll * b[i] % mod - b[i] * b[i] % mod * tmp[i] % mod) % mod + mod) % mod;
ntt(b, len, 1);
for(int i = siz; i < len; ++i) b[i] = 0;
}
洛谷 p4238 多項式乘法逆
#include #define ll long long
using namespace std;
template inline void read(temp & res)
const int maxn = 262200;
const ll mod = 998244353, g[2] = ;
ll qpow(ll a, ll p)
return res;
} namespace polynomial
} void ntt(ll p, int len, int type)
}} if(type == 1) }
void polymul(ll a, ll b, int siz)
ll tmp[maxn];
void polyinv(ll a, ll b, int siz)
polyinv(a, b, (siz + 1) >> 1);
int len = 1, l = (siz << 1); while(l) l >>= 1, len <<= 1;
for(int i = 0; i < siz; ++i) tmp[i] = a[i];
for(int i = siz; i < len; ++i) tmp[i] = 0;
setrev(len); ntt(tmp, len, 0); ntt(b, len, 0);
for(int i = 0; i < len; ++i) b[i] = ((2ll * b[i] % mod - b[i] * b[i] % mod * tmp[i] % mod) % mod + mod) % mod;
ntt(b, len, 1);
for(int i = siz; i < len; ++i) b[i] = 0; }}
int n, m;
ll a[maxn], b[maxn];
int main()
多項式求逆
你可能覺得這篇部落格很像網上的另一篇,我會告訴你我是抄的無可奉告 w 首先我們來講一些基礎的定義 多項式的度 就是這個多項式的最高次項的次數,記做deg a 對於多項式a x b x 唯一存在多項式q x r x 滿足a x b x q x r x 並且deg r deg b 那麼我們稱q x 為a...
多項式求逆
問題 求多項式 g x 滿足 f x g x equiv 1 pmod q1 這是什麼意思?a1 即 f x g x 最後只有常數項係數為 1 其餘係數都為 0 q2 為什麼要求模 x n a2 這是為了將 n 次方以上的項全都除去,否則 g x 會有無窮多項。用倍增的方法可以 o n log n ...
多項式求逆
給定乙個多項式 f x 請求出乙個多項式 g x 滿足 f x times g x equiv 1 mathrmx n 假設我們已經求得了 g 0 x 滿足 f x times g 0 x equiv 1 mathrmx frac 現在求 f x times g x equiv 1 mathrmx ...