Luogu 4238 模板 多項式求逆

2022-06-13 02:27:10 字數 2865 閱讀 3660

瘋狂補板中。

考慮倍增實現。

假設多項式只有乙個常數項,直接對它逆元就可以了。

現在假如要求$g(x)$

$$f(x)g(x) \equiv 1 (\mod x^n)$$

而我們已經求出了$h(x)$

$$f(x)h(x) \equiv 1(\mod x^ \right \rceil})$$

兩式相減,

$$f(x)(g(x) - h(x)) \equiv 0(\mod x^ \right \rceil})$$

$f(x) \mod  x^ \right \rceil}$一定不會是$0$,那麼

$$g(x) - h(x) \equiv 0(\mod x^ \right \rceil})$$

兩邊平方,

$$g(x)^2 + h(x)^2 - 2g(x)h(x) \equiv 0(\mod x^n)$$

注意到後面的模數也平方了。

因為多項式$g(x) - h(x)$次數$\in [0, \left \lceil \frac \right \rceil]$的項的係數全都是$0$,所以平方之後次數在$[0, n]$之間的項的係數也全都是$0$。

兩邊乘上$f(x)$,

$$f(x)g(x)^2 + f(x)h(x)^2 - 2f(x)g(x)h(x) \equiv g(x) + f(x)h(x)^2 - 2h(x) \equiv 0(\mod x^n)$$

就得到了

$$g(x) \equiv 2h(x) - f(x)h(x)^2(\mod x^n)$$

遞迴實現比較清爽,非遞迴的比遞迴的快挺多的。

時間複雜度為$o(nlogn)$。

實現的時候有兩個小細節:

1、$h(x)$的長度是$\frac$的,$f(x)$的長度是$n$,所以$f(x)h(x)^2$的長度是$2n$。

2、遞迴的時候注意那個上取整符號。

code:

#include #include 

#include

using

namespace

std;

typedef

long

long

ll;const

int n = 1

<< 20

;int

n;ll f[n], g[n];

namespace

poly ;

intlim, pos[l];

inline ll fmul(ll x, ll y, ll p)

return

res;

}inline ll fpow(ll x, ll y, ll p)

return

res;

}inline

void prework(int

len)

inline

void ntt(ll *c, ll opt, ll p) }}

if (opt == -1

) }

/*inline ll get(int k, ll p)

*/ll f[l], g[l];

void inv(ll *a, ll *b, int

len, ll p)

inv(a, b, (len + 1) >> 1

, p);

prework(len

<< 1

);

for (int i = 0; i < lim; i++) f[i] = g[i] = 0

;

for (int i = 0; i < len; i++) f[i] = a[i], g[i] =b[i];

ntt(f,

1, p), ntt(g, 1

, p);

for (int i = 0; i < lim; i++) g[i] = g[i] * (2ll - f[i] * g[i] % p + p) %p;

ntt(g, -1

, p);

for (int i = 0; i < len; i++) b[i] =g[i];

}};template

inline

void read(t &x)

intmain()

遞迴版

#include #include 

using

namespace

std;

typedef

long

long

ll;const

int n = 3e5 + 5

;const ll p =998244353ll;

intn, lim, pos[n];

ll a[n], f[

2][n], tmp[n];

template

inline

void read(t &x)

template

inline

void swap(t &x, t &y)

inline ll fpow(ll x, ll y)

return

res;

}inline

void ntt(ll *c, int

opt) }}

if (opt == -1) }

intmain()

--dep;

for (int i = 0; i < n; i++)

printf(

"%lld%c

", f[dep & 1][i], i == (n - 1) ? '

\n' : '');

return0;

}

非遞迴版

luoguP4238 模板 多項式求逆

令 b x 表示 a x 在 x 下的逆 那麼有 b x 2b x ab x 遞迴一下即可 在 len 1 時直接對常數項求逆即可 這裡一定要注意!取逆的時候是預設 x 的,所以如果在多項式後面多加幾個 0 的話逆是會變的!因為模數改變了!code include include include i...

洛谷P4238 模板 多項式求逆

題目傳送門 題目分析 放個板子在blog上,以後複習的時候用。注意每一次呼叫poly rev 的時候都要重新計算一遍rev陣列,而且要先清0。求modxm modx m下的逆元的時候,注意ntt的次數界要開到2m,因為a x g2 x a x g2 x 的次數界加起來為m m2 m 2 2 2m 2...

模板 多項式求逆

蒟蒻寫題解實在不易 多項式最高次數為度,多項式 a 的度記為 deg a 多項式取模的意義 將多項式 a 記作余式 a x q x b x r x 則 a x equiv r x mod b x 在有模數 mod 的情況下,f x g x equiv 1 mod x n 的具體情況 f x g x ...