多項式全家桶系列
前置知識
FFT,NTT等數論基礎知識
多項式求逆
題意
給定一個多項式$F(x)$,求一個多項式$G(x)$,使得$F(x)G(x) \equiv 1\qquad\mod x^n$
$n \le 10^5$
方法
在處理多項式問題中,二分法是一個很常見的方法
我們假設求出了在模$\lfloor\frac n2\rfloor$上$F(x)$的逆$H(x)$
那麼我們有
$$F(x)H(x)\equiv 1\qquad\mod x^{\lfloor\frac n2\rfloor}$$
由題,顯然可得
$$F(x)G(x)\equiv 1\qquad\mod x^{\lfloor\frac n2\rfloor}$$
兩式相減
$$G(x)-H(x)\equiv 0\qquad\mod x^{\lfloor\frac n2\rfloor}$$
兩邊平方
$$G^2(x)-2G(x)H(x)+H^2(x)\equiv 0\qquad\mod x^n$$
兩邊同乘$F(x)$
$$F(x)G^2(x)-2F(x)G(x)H(x)+F(x)H^2(x)\equiv 0\qquad\mod x^n$$
由$G(x)F(x)\equiv 1\qquad\mod x^n$得
$$G(x)-2H(x)+F(x)H^2(x)\equiv 0\qquad\mod x^n$$
即
$$G(x)\equiv 2H(x)-F(x)H^2(x)\qquad\mod x^n$$
邊界條件:只剩常數項時所求逆即為該數的逆元。
getinv上述程式碼中$a$為原陣列,$b$為所求逆,$c$為輔助陣列
多項式對數函式
題意
給定多項式$F(x)$,求一個多項式$G(x)$,使得$G(x)\equiv\ln F(x)\qquad\mod x^n$
$n\le 10^5$
方法
設函式$f(x)=\ln(x)$
則我們要求的式子變為
$$G(x)\equiv f(F(x))\qquad\mod x^n$$
兩邊求導,根據複合函式求導$f(g(x))'=f'(g(x))g'(x)$,得
$$G'(x)\equiv\frac{F'(x)}{F(x)}\qquad\mod x^n$$
對$F(x)$求導得$F'(x)$,求逆得$\frac{1}{F(x)}$,兩式相乘得$G'(x)$,再積分則可得$G(x)$
多項式求導
已知$$F(x) = \sum_{i = 0}^{n} a_ix^i$$
則$$F'(x) = \sum_{i=0}^{n-1} a_{i+1}*(i+1)x^i$$
假設$F(x) = 4x^3+5x^2+2x+4$,那麼$F'(x)=12x^2+10x+2$
多項式積分
求導的逆運算。
對於$a[i]$,直接乘上$i$的逆元即可。
View Code多項式exp
題意
給定多項式$F(x)$,求一個多項式$G(x)$,使得$G(x)\equiv e^{F(x)}\qquad\mod x^n$
$n\le 10^5$
方法
過程需要使用牛頓迭代和泰勒展開,因此只給結論
假設我們求得$H(x)$滿足
$$H(x)\equiv e^{F(x)}\qquad\mod x^{\lfloor\frac n2\rfloor}$$
則
$$G(x)\equiv H(x)(1-\ln(H(x))+F(x))\qquad\mod x^n$$
View Code多項式快速冪
題意
給定多項式$F(x)$與整數$m$,求多項式$G(x)$,使得$G(x)\equiv F^m(x)\qquad\mod x^n$
$n\le 10^5,m\le 10^{10^5}$
方法
$$G(x)\equiv F^m(x)\qquad\mod x^n$$
兩邊同時取對數,得
$$\ln G(x)\equiv m\ln F(x)\qquad\mod x^n$$
求出$\ln G(x)$後再進行exp即可。
View Code但是ln與exp預設常數項為$1$,當多項式常數項不為1時需要特殊處理
當常數項為$0$時,需要將多項式平移至常數項不為$0$
若常數項不為$1$,則需要將所有係數同時除以常數項
多項式開根
題意
給定多項式$F(x)$,求多項式$G(x)$,使得$G^2(x)\equiv F(x)\qquad\mod x^n$
$n\le 10^5$
方法
假設$H(x)$滿足$$H^2(x)\equiv F(x)\qquad\mod x^{\lfloor\frac n2\rfloor}$$
顯然有$$G^2(x)\equiv F(x)\qquad\mod x^{\lfloor\frac n2\rfloor}$$
那麼有$$G(x)\equiv H(x)\qquad\mod x^{\lfloor\frac n2\rfloor}$$
把$H(x)$扔過來,兩邊平方,得$$G^2(x)-2H(x)G(x)+H^2(x)\equiv 0\qquad\mod x^n$$
$$F(x)-2H(x)G(x)+H^2(x)\equiv 0\qquad\mod x^n$$
$$G(x)\equiv \frac{H^2(x)+F(x)}{2H(x)}\qquad\mod x^n$$
邊界條件:假設給定多項式的常數項為$x$,我們要找到一個$y$,使$y^2\equiv x \mod 998244353$
二次剩餘定理
若$y^2\equiv x\qquad\mod p$,則稱$y$是$x$在模$p$意義下的二次剩餘
定義勒讓德符號
$$ (\frac np)=\left\{ \begin{aligned} x & = 1 \qquad n在模p意義下是二次剩餘\\ y & = 0 \qquad p | n \\ z & = -1 \qquad n在模p意義下是二次非剩餘 \end{aligned} \right. $$
那麼我們有尤拉判別準則
$$(\frac np)\equiv n^{\frac {p-1}2}\qquad\mod p$$
Cipolla演算法流程
第一步,判斷方程是否有解
第二步,隨機找一個$a$,使得數$w=(a^2-x)%p$,且$w$在模$p$意義下為非二次剩餘
第三部,找到一個解$y\equiv (a+\sqrt(w)^{\frac{p +1}2})\qquad\mod p$,因為$\sqrt w$不存在,所以將$\sqrt w$當作虛數即可
struct cp { int x, y; cp(int xx = 0, int yy = 0) {x = xx, y = yy;} cp operator * (cp A) {return (cp){(A.x * x % Mod + y * A.y % Mod * w % Mod) % Mod, (A.x * y % Mod + A.y * x % Mod) % Mod};} }; int Qpow(cp a, int b) { cp res(1, 0); while(b) { if(b & 1) res = res * a; a = a * a; b >>= 1; } return res.x; } int Calc(int x) { srand(time(0)); if(qpow(x, (Mod - 1) >> 1) == Mod - 1) return -1; while(1) { int a = rand() * rand() % Mod; w = (a * a % Mod - x + Mod) % Mod; if(qpow(w, (Mod - 1) >> 1) == Mod - 1) return Qpow(cp(a, 1), (Mod + 1) >> 1); } } void Sqrt(int len, int *a, int *b) { if(len == 1) { b[0] = Calc(a[0]); b[0] = min(b[0], Mod - b[0]); return; } Sqrt((len + 1) >> 1, a, b); memset(d, 0, sizeof(d)); getinv(len, b, d); getl(len << 1); for(int i = 0; i < len; i++) c[i] = a[i]; for(int i = len; i < lim; i++) c[i] = 0; ntt(b, 1); ntt(d, 1); ntt(c, 1); for(int i = 0; i < lim; i++) b[i] = (b[i] + c[i] * d[i] % Mod) % Mod * qpow(2, Mod - 2) % Mod; ntt(b, -1); for(int i = len; i < lim; i++) b[i] = 0; }View Code