多项式专题

多项式

点值表示法和系数表示法

代数基本定理: 一个\(n-1\)次多项式在复数域上有且只有\(n-1\)个根

多项式有点值表示法和系数表示法两种

  • 系数表示法:\(A(x)=\sum_{i=0}^{n-1}a_ix^i\)
  • 点值表示法:\(y_i=\sum_{j=0}^{n-1}a_jx_i^j\)

定理: 一个n-1次多项式在n个不同点的取值唯一确定了该多项式

证明:

考虑反证法,假设命题不成立,则存在两个\(n-1\)次多项式\(A(x)\)\(B(x)\)\(\forall i\in[0,n-1],A(x_i)=B(x_i)\)

\(C(x)=A(x)-B(x)\),那么\(C(x)\)至多是一个\(n-1\)次多项式且\(\forall i\in[0,n-1],C(x_i)=0\)
也就是\(C(x)\)\(n\)个根,与代数基本定理不符合

已知多项式点值表示法求系数表示法的过程被称为插值

拉格朗日插值

问题

已知平面上\(n+1\)个点,有一条过\(n+1\)个点的曲线(多项式)
,求该在该曲线某一位置的取值

法1 高斯消元

法2 拉格朗日插值

已知\(n+1\)个点的坐标为\(x_i,y_i\),函数在\(x=k\)时的取值

\[f(k)=\sum_{i=0}^{n}y_i \prod_{i\neq j}\frac{k-x_j}{x_i-x_j} \]

证明

\[f(x)-f(a)=(a_0-a_0)+a_1(x-a)+a_2(x^2-a^2)+\cdots+a_n(x^n-a^n) \\f(x)-f(a)\equiv0 \pmod{(x-a)} \\f(x)\equiv f(a) \pmod{(x-a)} \]

同样,\(n\)个点的坐标为\(x_i,y_i\)

\[\begin{cases} f(x)\equiv y_1\pmod{(x-x_1)} \\f(x)\equiv y_2\pmod{(x-x_2)} \\ \cdots \\f(x)\equiv y_n\pmod{(x-x_n)} \end{cases} \]

\(CRT\)可知

\[M=\prod_{i=1}^{n}(x-x_i) \\m_i=\frac{M}{x-x_i}=\prod_{i\neq j}(x-x_j) \]

由于\(x-x_j\)\(x-x_j-(x-x_i)\) 在模多项式 \(x-x_i\) 的意义下是等价的

\(x-x_j\equiv x_i-x_j\pmod{(x-x_i)}\)

所以有

\(m^{-1}_{i}=\prod_{i\neq j}\frac 1{x_i-x_j}\)

所以有

\[f(x)=\sum_{i=1}^{n}y_im_im_i^{-1}\equiv\sum_{i=1}^ny_i\prod_{i\neq j\frac{x-x_i}{x_i-x_j}}\pmod{M}\]

所以在模意义下\(f(x)\)就是唯一的,即

\[f(x)=\sum_{i=1}^{n}y_i\prod_{i\neq j}\frac{x-x_j}{x_i-x_j} \]

求某一点处的函数值\(O(n^2)\)

求出整个多项式\(O(n^3)\)

在x取值连续的时候的做法

由于\(x_i\)连续,所以将其换为\(i\)

\[f(k)=\sum_{i=0}^{n}y_i\prod_{i\neq j}\frac{k-j}{i-j} \]

分母维护前缀积和后缀积

分子维护阶乘

\[fac[i]=i! \\pre[i]=\prod_{j=0}^{i}(k-j),suf[i]=\prod_{j=i}^{n}(k-j) \\ \\ f(k)=\sum_{i=0}^{n}y_i\frac{pre[i-1]\times suf[i+1]}{fac[i]\times fac[n-i]\times (-1)^{n-i}} \]

时间复杂度:

求函数值\(O(n)\)

求多项式\(O(n^3)\)

由此,我们发现普通的拉格朗日插值在增减坐标时需要全部重新计算

并且对求多项式并没有任何的优化

所以考虑进行进一步的优化

重心拉格朗日插值法

\[g(k)=\prod_{i=0}^n(k-x_i) \\t_i=\prod_{i\neq j}\frac{1}{x_i-x_j}\]

\[f(k)=g(k)\sum_{i=0}^n\frac{t_iy_i}{k-x_i} \]

那么这样有什么用呢?

对于\(\lceil求出次数不超过n的多项式\rfloor\)问题,枚举每一个\(x_i\),计算每一个\(\frac{g(k)}{k-x_i}\),这样得到的就是\(x_i\)对应的多项式,然后我们将所求出来的\(n+1\)个多项式的系数相加即可以得到我们所想要的多项式

举个例子

对于多项式\(f(k)=a_0+a_1k+a_2k^2\)

\[\begin{cases} x_1=1,y_1=9 \\x_2=2,y_2=20 \\x_3=3,y_3=37 \end{cases} \]

所以有

\[\begin{cases} \frac{g(k)}{k-x_1}=(k-2)(k-3)=k^2+5k+6 \\\frac{g(k)}{k-x_2}=(k-1)(k-3)=k^2-4k+3 \\\frac{g(k)}{k-x_3}=(k-1)(k-2)=k^2-3k+2 \end{cases} \]

还有系数\(\sum_{i=0}^n\frac{t_iy_i}{k-x_i}\),计算出来分别为\(\frac92,-20,\frac {37}2\)

将系数乘在上面的式子中

\[\begin{cases} \frac92k^2+\frac{45}2k+27 \\-20k^2+80k-60 \\\frac {37}2k^2-\frac {111}2k+37 \end{cases} \]

将三个式子系数相加

即可得到\(f(k)=3k^2+2k+4\)

考虑一下这个过程,由于所除的\(k-x_i\)为二项式,时间复杂度为\(O(n)\),枚举\(n\)项,所得的总时间复杂度为\(O(n^2)\)

此外,如果我们想要新加入一个点\((x,y)\),我们只需增加一次对\(i=n+1\)枚举,给\(g(k)\)乘上\(k-x\),同时让每一个\(t_i\)除以\(x_i-x\),这个过程的复杂度为\(O(n)\),因此如果我们想要插\(n\)个点进来,复杂度就为\(O(n^2)\)

所以重心拉格朗日插值,在有关多项式求函数值、求多项式系数上完全优于高斯消元

单位根

\(\omega_n=cos\frac{2\pi}{n}+isin\frac{2\pi}{n}\)

\(\omega_n^k=cos\frac{2k\pi}{n}+isin\frac{2k\pi}{n}\)

单位根的性质

\(1.\omega_n^k=\omega_{rn}^{rk}\)

\(2.(\omega_n^k)^n=1\)

\(3.\omega_{2n}^k=-\omega_{2n}^{k+n}\)

\(4.\omega_n^a\times \omega_n^b=\omega_n^{ab}\)

\(5.\omega^0_n=\omega^n_n=1\)

为什么我们需要傅里叶变换

多项式有两种表示方法——系数表示法和点值表示法

系数表示法就是经典的

\[f(x)=\sum_{n\ge 0}a_nx^n \]

我们在重心拉格朗日插值法中,已知任意\(n+1\)个点的坐标,便可以\(O(n^2)\)地求出一个多项式的各项系数

这也说明,这\(n+1\)个点所对应的多项式是唯一确定的,这样用点和坐标表示多项式的方法叫做点值表示法

对于多项式,\(f(x),\deg f(x)=n\)它写成这个样子

\[\lbrace(x_0,f(x_0)),(x_1,f(x_1),\cdots,(x_{n+1},f(x_{n+1})))\rbrace \]

那么它有什么用呢?

已知两个多项式\(f(x),g(x)\),有\(\deg f(x)=n,\deg g(x)=m\),有\(\deg f(x)g(x)=n+m\),于是我们可以找\(n+m+1\)个点,分别带入\(f(x),g(x)\)

\[\lbrace(x_0,f(x_0)g(x_0)),(x_1,f(x_1)g(x_1),\cdots,(x_{n+m+1},f(x_{n+m+1})g(x_{n+m+1})))\rbrace \]

我们发现这个过程是\(O(n)\)的,很优秀,是吧\(\cdots\)

是吗?

如果只是随机取点,点值表示转成系数表示的复杂度暂时只能做到\(O(n^2)\),这是我们无法接受的

于是我们就需要\(FFT\)和它的单位根了

那么\(FFT\)完成的操作就是:

  • 把已知的一个多项式转化成对应的点值表示;
  • 把已知的点值表示转换成对应的多项式。

复杂度都是 \(O(n\log n)\)

快速傅里叶变换

Part 1 DFT

\(f(x)=(a_0+a_2x^2+a_4x^4+\cdot\cdot\cdot+a_{n-2}x^{n-2})+(a_1x+a_3x^3+a_5x^5+\cdot\cdot\cdot+a_{n-1}x^{n-1})\)

\(f_1(x)=a_0+a_2x^1+a_4x^2+\cdot\cdot\cdot+a_{n-2}x^\frac{n-2}{2}\)

\(f_2(x)=x(a_0+a_2x^1+a_4x^2+\cdot\cdot\cdot+a_{n-2}x^\frac{n-2}{2})\)

则有

\(f(x)=f_1(x^2)+f_2(x^2)\)

\(x=\omega^k_n\) 带入

\(f(\omega^k_n)=f1(\omega^{2k}_n)+\omega^k_nf_2(\omega^{2k}_n)\)

\(=f_1(\omega^k_{\frac n2})+\omega^k_nf_2(\omega^k_\frac n2)\)

\(x=\omega^{k+\frac n2}_n\)

\[f(\omega^{k+\frac n2}_n)=f_1(\omega^{2k+n}_n)+\omega^{k+\frac n2}_nf_2(\omega^{2k+n}) \]

\[=f_1(\omega^{k}_\frac n2)-\omega_n^k f_2(\omega^{k}_\frac n2) \]

这也就意味着,如果可以求出\(f_1(\omega^{k}_\frac n2)\)\(f_2(\omega^{k}_\frac n2)\),我们即可以求出\(f(\omega^{k+\frac n2}_n)\)\(f(\omega^{k}_n)\)

多项式最终会递归到只有一个常数项

这样就用\(O(nlogn)\)的复杂度将系数表示转成了点值表示

将点值表示后的两个多项式相乘得到它们乘积的点值表示

Part 2 IDFT

考虑如何将点值表示转成系数表示

\((y_0,y_1,y_2,\cdot\cdot\cdot,y_{n-1})\)\((a_0,a_1,a_2,\cdot\cdot\cdot,a_{n-1})\)的点值表示

设另一个向量(复数)为

\(c_k=\sum_{i=0}^{n-1}y_i(w_n^{-k})^i\)

即多项式\(A(x)=y_0+y_1x+y_2x^2+\cdot\cdot\cdot+y_{n-1}x^{n-1}\)\(\omega_n^0,\omega_n^{-1},\omega_n^{-2},\cdot\cdot\cdot,\omega_n^{-(n-1)}\)处的点值表示

其中\(y_i=f(\omega_n^i)\)

式子:

\[c_k=\sum\limits_{i=0}^{n-1}y_i(\omega_n^{-k})^i \\ =\sum_{i=0}^{n-1}(\sum_{j=0}^{n-1}a_j(\omega_n^i)^j)(\omega_n^{-k})^i \\ =\sum_{i=0}^{n-1}(\sum_{j=0}^{n-1}a_j(\omega^j_n)^i(\omega_n^{-k})^i) \\ =\sum_{i=0}^{n-1}\sum_{j=0}^{n-1}a_j(\omega_n^{j-k})^i \\ =\sum_{j=0}^{n-1}a_j\sum_{i=0}^{n-1}(\omega_n^{j-k})^i \]

\(S(x)=\sum_{i=0}^{n-1}x^i\)

\(x=\omega^k_n\)带入得

一式\(S(\omega_n^k)=\sum_{i=0}^{n-1}\omega_n^{ik}\)

二式\(\omega_n^kS(\omega_n^k)=\sum_{i=1}^{n}\omega_n^{ik}\)

二式相减得

\[\omega_n^kS(\omega_n^k)-S(\omega_n^k)=(\omega_n^k)^n-1 \\ S(\omega_n^k)=\frac{(\omega_n^k)^n-1}{\omega_n^k-1} \\ S(\omega_n^k)=\frac{0}{\omega_n^k-1} \]

\(k\neq0 ,S(\omega_n^k)=0\)

\(k=0,S(\omega_n^0)=n\)

考虑刚才推的式子

\[c_k=\sum_{j=0}^{n-1}a_j\sum_{i=0}^{n-1}(\omega_n^{j-k})^i \]

\(j\neq k\)时,值为 \(0\)

\(j=k\)时,值为 \(n\)

因此有

\[c_k=na_k \\ a_k=\frac{c_k}{n} \]

于是我们得到了点值与系数的关系式了

\[[(\omega_n^{-0},A(\omega_n^{-0})),(\omega_n^{-1},A(\omega_n^{-1})),(\omega_n^{-2},A(\omega_n^{-2})),\cdot\cdot\cdot,(\omega_n^{-(n-1)},A(\omega_n^{-(n-1)}))] \\ \Rightarrow [(\omega_n^{-0},na_0),(\omega_n^{-1},na_1),(\omega_n^{-2},na_2),\cdot\cdot\cdot,(\omega_n^{-(n-1)},na_{-(n-1)})] \]

将 DFT 中的单位根改为\(\omega_n^{-k}\),求解出\(na_k\)后,除以\(n\) 即为所要求的系数

FFT的优化方法

三次变两次

考虑下面这个式子

\[(a+bi)^2=a^2-b^2+2abi \]

\(a=f(x),b=g(x)\)

我们一次 DFT 计算出\(f^2(x)\),它的虚部即为\(f(x)g(x)\)

在 IDFT 一次就可以得到答案

蝴蝶变换

递归的常数太大

不失一般性的,设\(k\)为偶数。对于初始是

\[\omega_n^0,\omega_n^1,\omega_n^2,\cdot\cdot\cdot,\omega_n^k \]

的序列,在递归的第一层会将其拆分为

\[\omega_n^0,\omega_n^2,\omega_n^4,\cdot\cdot\cdot,\omega_n^k \]

\[\omega_n^1,\omega_n^3,\omega_n^5,\cdot\cdot\cdot,\omega_n^{k-1} \]

两部分。

也就是说对于任意的\(\omega_n^i\),若 \(i\) 在二进制下最后一位为\(0\)\(\omega_n^i\) 会被分配到前半部分,否则会被分配到后半部分。

换言之,当前 \(i\) 在二进制下的倒数第 \(j\) 位决定了它在当前长度为 \(2^{k-j+1}\) 的区间中是被分配到长度为 \(2^{k-j}\) 的前半部分还是长度为 \(2^{k-j}\) 的后半部分。

可以发现 \(\omega_n^i\) 在最终的序列中的位置下标相当于 \(i\) 二进制下翻转得到的数

然后就可以愉快地递推了

NTT快速数论变换

我们为什么需要NTT

\(FFT\)在计算过程中有着大量的精度丢失,导致答案计算并不准确,这是我们所不能接受的

参考对除法的处理,我们考虑将\(FFT\)带到模意义下

于是我们要考虑如何将\(FFT\)的单位根改到模意义下,很自然地想到了原根,为什么?

考虑原根的定义

\(在模m的意义下,\exist a \in N^*,使得a^1,a^2,a^3,\cdot\cdot\cdot,a^{\varphi(m)}两两不同\)

取模的过程很像是一个循环,这与我们单位根在复平面上绕圈的过程相仿

我们知道单位根有如下的性质

\(1.\omega_n^k=\omega_{rn}^{rk}\)

\(2.(\omega_n^k)^n=1\)

\(3.\omega_{2n}^k=-\omega_{2n}^{k+n}\)

\(4.\omega_n^a\times \omega_n^b=\omega_n^{ab}\)

\(5.\omega^0_n=\omega^n_n=1\)

那么只有当原根与单位根性质完全相同时,我们才可以等价替换,定义

\[g_n^k=(a^{\frac{m-1}{n}})^k \]

我们来检验一下

\[1.g_{rn}^{rk}=(a^{\frac{m-1}{rn}})^{rk}=(a^{\frac{m-1}{n}})^k=g_n^k \]

由费马小定理

\[a^{p-1}\equiv1\pmod{p} \]

\[2.(g_n^k)^n=(a^{m-1})^k=1 \]

\[3.g_{2n}^k=(a^{\frac{m-1}{2n}})^k(a^{\frac{m-1}{2n}})^n=g_{2n}^ka^{\frac{m-1}{2}} \]

由于原根互不相同和费马小定理,有

\[a^{\frac{m-1}{2}}\equiv-1\pmod{m} \]

所以

\[3.g_{2n}^k=-g_{2n}^{k+n} \]

\(4.5.\)均采用类似上面的证明方法,由此我们证明了原根可以完美替代单位根,这就是\(NTT\)

注意只有当\(n\mid(m-1)\)的时候\(NTT\)才可以正确地运行

\(n\)总是\(2\)的整数次方,所以\(m-1\)必然可以写成\(2^rd+1\)的形式

常见的\(NTT\)模数:

469762049

998244353

1004535809

任意模数NTT

如果模数不是\(NTT\)模数该怎么办呢?

有一个想法是我们可以先用\(NTT\)模数算出系数,然后再对题目要求的模数取模

但是如果题目的系数大于\(NTT\)模数,那我们就无法计算出准确的系数了

\(LuoguP4245 【模板】任意模数多项式乘法\),这道题,其极限情况可以达到\(10^9\times 10^9\times 10^5=10^{23}\),直接\(NTT\)必然寄掉

既然一个模数不够用,那我们直接参考哈希,将模数扩展成三个,只需要取三个模数,使其乘积大于极限情况,最后再用中国剩余定理合并就好了

注意在中国剩余定理时会爆long long,所以可以全部定义成__int128

分治NTT

问题

给定序列 \(g_{1\dots n - 1}\),求序列 \(f_{0\dots n - 1}\)

其中 \(f_i=\sum_{j=1}^if_{i-j}g_j\),边界为 \(f_0=1\)

答案对 \(998244353\) 取模

题解

直接暴力\(O(n^2)\)

如果直接\(NTT\),复杂度为\(O(n^2\log n)\)

显然这是一个比暴力还要劣的解

所以我们考虑\(CDQ\)分治

要求区间\([l,r]\)的答案,假设我们已经求出了区间\([l,mid]\),现在考虑右半边的答案,令\(x\in [mid+1,r]\),那么考虑左子区间对它的贡献为

\[f_x=\sum_{i=l}^{mid}f_ig_{x-i} \]

这是一个卷积的形式,可以利用\(NTT\)计算

复杂度为\(O(n\log^2 n)\)

莫比乌斯变换与莫比乌斯反演

莫比乌斯变换

\[f(S)=\sum_{T\subseteq S} g(T) \]

莫比乌斯反演

\[g(S)=\sum_{T\subseteq S}(-1)^{|S|-|T|} f(T) \]

证明

\[\sum_{i=0}^n(-1)^{i}\binom{n}{i}=[n=0] \]

可得

\[ \sum_{T\subseteq S} (-1)^{|T|}=[S=\varnothing]\\ \begin{aligned} g(S)&=\sum_{T\subseteq S} [S-T=\varnothing] g(T)\\ &=\sum_{T\subseteq S}\sum_{P\subseteq S-T} (-1)^{|P|} g(T)\\ &=\sum_{P\subseteq S}\sum_{T\subseteq S-P} (-1)^{|P|} g(T)\\ &=\sum_{P\subseteq S}(-1)^{|P|}\sum_{T\subseteq S-P} g(T)\\ &=\sum_{P\subseteq S}(-1)^{|P|}f(S-P)\\ &=\sum_{T\subseteq S} (-1)^{|S|-|T|} f(T) \end{aligned} \]

证毕。

合并卷积

定义

\[h(S)=f(S)*g(S)=\sum_{A\subseteq S}\sum_{B\subseteq S} f(A)g(B)[A\cup B=S] \]

\(h\)\(f\)\(g\) 的合并卷积。

\(\hat h(S)\)\(h(S)\) 的莫比乌斯变换,则

\[\begin{aligned} \hat h(S)&=\sum_{T\subseteq S}\sum_{A\subseteq T}\sum_{B\subseteq T} f(A)g(B)[A\cup B=T]\\ &=\sum_{A\subseteq S}\sum_{B\subseteq S} f(A)g(B)[A\cup B\subseteq S]\\ &=\sum_{A\subseteq S}\sum_{B\subseteq S} f(A)g(B)\\ &=\sum_{A\subseteq S}f(A)\sum_{B\subseteq S} g(B)\\ &=\hat f(S)\hat g(S) \end{aligned} \]

这启发我们计算 \(f\)\(g\) 的合并卷积时,可以先将 \(f\)\(g\) 分别做莫比乌斯变换,然后相乘,得到 \(h\) 的莫比乌斯变换 \(\hat h\),再对 \(\hat h\) 做莫比乌斯反演,即得到 \(f\)\(g\) 的合并卷积 \(h\)

快速莫比乌斯变换

快速莫比乌斯变换FMT

要对所有的\(S\),求

\[\hat f(S)=\sum_{T\subseteq S} f(T) \]

定义

\[\hat f(S,i)=\sum_{T\subseteq S}f(T)[\{i+1,i+2,\dots,n\}\subseteq T] \]

那么有 \(\hat f(S,0)=f(S),\hat f(S,|S|)=f(\varnothing)\)
设集合 \(S\cap \{i\}=\varnothing\)

那么

\[\hat f(S\cup \{i\},i)=\hat f(S,i-1)+\hat f(S\cup\{i\},i-1) \]

因为
\(S\cap \{i\}=\varnothing\),所以 \(\hat f(S,i)=\hat f(S,i-1)\)

\(\hat f(S,i)\)表示 \(\{i+1,i+2,\dots,n\}\) 一定含于 \(T\),并且一定没有选 \(i\)
\(\hat f(S\cup\{i\},i-1)\) 表示 ${i+1,i+2,\dots,n} $一定含于 \(T\),并且一定选了 \(i\)
那么由加法原理即可知

\[\hat f(S\cup \{i\},i)=\hat f(S,i-1)+\hat f(S\cup\{i\},i-1) \]

那么我们递推 \(n\) 轮,即可求得 \(\hat f(S)\)
时间复杂度 \(O(n2^n)\)

void FMT(int *f)
{
    for(int i=0;i<n;++i)
        for(int j=0;j<(1<<n);++j)
            if(j&(1<<i)) f[j]+=f[j^(1<<i)];
}

这个过程相当于高维前缀和

IFMT快速莫比乌斯反演

跟FMT一样,不断递推,不过变成了减法。

void IFMT(int *f)
{
    for(int i=0;i<n;++i)
        for(int j=0;j<(1<<n);++j)
            if(j&(1<<i)) f[j]-=f[j^(1<<i)];
}

这个过程相当于高维差分

子集卷积

\[c_i=\sum_{j}\sum_{k}[j~and~k=\varnothing,j~or~k=i]a_jb_k \]

由于

\[[j~and~k=\varnothing,j~or~k=i]=[|j|+|k|=|i|,j~or~k=i] \]

因而可以将原集合按照元素个数分组,做\(FMT\),然后再\(n^2\)次结合,并做\(IFMT\),最终将结果累计

复杂度\(O(2^nn^2)\)

快速沃尔什变换

与/或卷积

  • 或卷积:\(c_i=\sum_{j}\sum_{k}[j~or~k=i]a_jb_k\)
  • 与卷积:\(c_i=\sum_{j}\sum_{k}[j~and~k=i]a_jb_k\)
    考虑如何求\(a\)\(b\)的或卷积:

引理:

\(j,k\subseteq i\),则\(j~or~k\subseteq i\),逆命题同样成立
\(j,k\supseteq i\),则\(j~and~k\supseteq i\),逆命题同样成立

\(a,b,c\)的高维前缀和分别为\(A,B,C\)

\[A_iB_i=(\sum_{j\subseteq i}a_j)(\sum_{k\subseteq i}b_k)=\sum_{j,k\subseteq i}a_ib_k=\sum_{k~or~j\subseteq i}a_ib_k=C_i \]

现在考虑已知\(C\)\(c\),本质上是一个反演
注意到

\[\sum_{r\subseteq p}(-1)^{|r|}=\sum_{k=0}^{|p|}C_{|p|}^k(-1)^k=[p=0]\\ \begin{aligned} c(p)&=\sum_{q\subseteq p}[p-q=0]c(q)\\&=\sum_{q\subseteq p}\sum_{r\subseteq (p-q)}(-1)^{|r|}c(q)\\&=\sum_{r\subseteq p}(-1)^{|r|}\sum_{q\subseteq (p-r)}c(q)\\&=\sum_{r\subseteq p}(-1)^{r}f(p-r)\\&=\sum_{r\subseteq p}(-1)^{|p|-|r|}C(r)\\ \end{aligned} \]

于是

\[C(S)=\sum_{T\subseteq S}c(T)\\ c(S)=\sum_{T\subseteq S}(-1)^{|S|-|T|}C(T) \]

因而做两遍高维前缀和再反推回去即可,复杂度\(O(2^nn)\)

与卷积即改为高维后缀和

inline void FWT_and(ll *a,ll t,int limit){//FWT:t=1;IFWT:t=-1
	for(int mid=1;mid<limit;mid=mid<<1){
		int n=mid<<1;
		for(int j=0;j<limit;j+=n){
			for(int k=0;k<mid;++k){
				a[j+k]+=t*a[j+k+mid]%mod;
				Mod(a[j+k]);
			}
		}
	}
	return ;
}

inline void FWT_or(ll *a,ll t,int limit){//FWT:t=1;IFWT:t=-1
	for(int mid=1;mid<limit;mid=mid<<1){
		int n=mid<<1;
		for(int j=0;j<limit;j+=n){
			for(int k=0;k<mid;++k){
				a[j+k+mid]+=t*a[j+k]%mod;
				Mod(a[j+k+mid]);
			}
		}
	}
	return ;
}

异或卷积

\[c_i=\sum_j\sum_k[j\oplus k=i]a_jb_k \]

快速沃尔什变换(FWT):

定义集合幂级数\(FWT(a)\),满足\(FWT(a)_i=\sum_{j=0}^{2^n-1}(-1)^{|i~and~j|}a_j\)
那么有:

\[\begin{aligned} FWT(c)_i&=\sum_{j=0}^{2^n-1}(-1)^{|i~and~j|}c_j\\&=\sum_{j=0}^{2^n-1}(-1)^{|i~and~ j|}\sum_{k=0}^{2^n-1}\sum_{l=0}^{2^n-1}[k\oplus l=j]a_kb_l\\ &=\sum_{k=0}^{2^n-1}\sum_{l=0}^{2^n-1}(-1)^{|(k\oplus l)~and~i|}a_kb_l\\&=\sum_{k=0}^{2^n-1}\sum_{l=0}^{2^n-1}(-1)^{|k~and ~i|}a_k(-1)^{|l ~and~i|}b_l\\&=FWT(a)_iFWT(b)_i\\ \end{aligned} \]

时间复杂度\(O(2^nn)\)
\(FMT\)可以看作是\(FWT\)在解决或卷积,与卷积时的特例

inline void FWT_xor(ll *a,ll t,int limit){//FWT:t=1;IFWT:t=mpow(2,mod-2)
	for(int mid=1;mid<limit;mid=mid<<1){
		int n=mid<<1;
		for(int j=0;j<limit;j+=n){
			for(int k=0;k<mid;++k){
				ll x=a[j+k],y=a[j+k+mid];
				a[j+k]=t*(x+y)%mod;Mod(a[j+k]);
				a[j+k+mid]=t*(x-y+mod)%mod;Mod(a[j+k+mid]);
			}
		}
	}
	return ;
}

多项式牛顿迭代

给定多项式\(g(x)\),求解关于多项式\(f(x)\)的方程

\[g(f(x))\equiv 0\pmod{x^n} \]

我们假设已经求出了\(f(x)\)\(n\)项的多项式\(f_0(x)\),显然有

\[f(x)-f_0(x)\equiv 0\pmod{x^n} \]

考虑\(g(f(x))\)\(x\)处泰勒展开

\[g(f(x))\equiv \sum_{i=0}^{\infty}\frac{g^{(i)}(f_0(x))}{i!}(f(x)-f_0(x))^i\pmod{x^n} \]

我们来考虑一件事情

对于\((f(x)-f_0(x))^k\),当\(k\)大于等于\(2\)时,显然有结论

\[(f(x)-f_0(x))^k\equiv 0\pmod{x^{2n}} \]

那么就有

\[g(f(x))\equiv g(f_0(x))+g'(f(x)-f_0(x)) \\f(x)\equiv f_0(x)-\frac{g(f_0(x))}{g'(f_0(x))}\pmod{x^{2n}} \]

递归计算即可

多项式 ln

已知一个多项式\(f(x)\),求下式中的多项式\(r(x)\)

\[\ln(f(x))\equiv r(x)\pmod{x^n} \]

解决这个问题之前,先介绍多项式求导和多项式积分

多项式求导

利用导数公式\(x^n=nx^{n-1},(kx)'=kx'\)即可

其中\(k\)是常数

多项式积分

利用公式

\[\int ax^n=\frac{a}{n+1}x^{n+1} \]

计算即可

回到原问题

\[\ln(f(x))\equiv r(x)\pmod{x^n} \\ \frac{f'(x)}{f(x)}\equiv r'(x)\pmod{x^n} \]

因此\(f'(x)\)乘上\(f(x)\)的逆元,再积个分就是\(r(x)\)

多项式exp

问题

已知一个多项式\(f(x)\),求\(r(x)\)

\[e^{f(x)}\equiv r(x)\pmod{x^n} \]

先对它两边\(\ln\)

\[f(x)\equiv\ln(r(x))\pmod{x^n} \]

\(g(r(x))=\ln(r(x))-f(x)\),则\(g(r(x))\equiv0\pmod{x^n}\),因此我们可以采用牛顿迭代法,假设我们已经求出了\(r(x)\)的前\(n\)\(r_0(x)\),有

\[r(x)\equiv r_0(x)-\frac{g(r_0(x))}{g'(r_0(x))}\pmod{x^{2n}}\\r(x)\equiv r_0(x)-\frac{\ln(r_0(x))-f(x)}{\frac{1}{r_0(x)}}\pmod{x^{2n}}\\r(x)\equiv r_0(x)(1-\ln(r_0(x))+f(x))\pmod{x^{2n}} \]

然后递归计算\(r(x)\)即可求出答案

多项式快速幂

给定\(f(x)\)与常数\(p\),求多项式\(r(x)\)使得

\[f^p(x)\equiv r(x)\pmod{x^n} \]

法1

直接快速幂套上多项式乘法,时间复杂度\(O(n\log n\log p)\)

法2

考虑到\(x=e^{\ln x}\),所以

\[r(x)=e^{p\ln f(x)} \]

于是我们可以考虑先计算\(\ln f(x)\),将它的各项系数乘\(p\)得到\(p\ln f(x)\),再做一个多项式\(\exp\)即可

复杂度\(O(n\log n)\)

多项式乘法的技巧

\(FFT/NTT\)可以快速求下面这个式子

\[c_i=\sum_{j=0}^ia_jb_{i-j} \]

如果要求的形式长下面这个样子

\[c_i=\sum_{j=0}^{n-i}a_jb_{i+j} \]

这不是我们想要的卷积形式,于是可以考虑将\(a\)翻转

\[d_i=\sum_{j=0}^{n-i}a_{n-j+1}b_{i+j} \]

由于\(n+1-j+i+j=n+i+1\)\(j\)无关,所以我们将翻转后的\(a\)与原来的\(b\)做一下卷积,然后将得到\(d\)序列,有\(c_i=d_{n+i+1}\)

多项式求逆

问题

给定多项式\(f(x)\) ,求\(f^{-1}(x)\)

做法

首先,易知

\[[x^0]f^{-1}(x)=-([x^0]f(x))^{-1} \]

假设已经求出\(f(x)\)在模\(x^{\lceil\frac n2 \rceil}\)意义下的逆元\(f_0^{-1}(x)\)。有:(均为模意义下)

\[f(x)f_0^{-1}(x)=1 \\f(x)f^{-1}(x)=1 \]

因此

\[f^{-1}(x)-f_0^{-1}(x)=0 \]

两边平方,变为模\(x^n\)意义下

\[f^{-2}(x)-2f^{-1}(x)f_0^{-1}+f_0^{-2}=0 \]

同时乘\(f(x)\)并移项

\[f^{-1}(x)=f_0^{-1}(x)(2-f(x)f_0^{-1}(x)) \]

递归计算即可

时间复杂度\(O(nlogn)\)

多项式除法(取模)

问题:

给定多项式\(f(x),g(x)\),求\(g(x)\)\(f(x)\)的商\(Q(x)\)与余数\(R(x)\)

考虑构造系数翻转的变换

\[f^R(x)=x^{\deg f}f(\frac 1x) \]

进行推导,设\(n=\deg f,m=\deg g\),两边乘上\(x^n\)并将\(x\)更换为\(\frac1x\)

\[f(x)=g(x)Q(x)+R(x) \\x^nf(\frac 1x)=x^{n-m}Q(\frac 1x)x^mg(\frac 1x)+x^{n-m+1}x^{m-1}R(\frac 1x) \\f^R(x)=Q^R(x)g^R(x)+x^{n-m+1}R^R(x) \]

此时我们发现,如果我们两边取模\(x^{n-m+1}\),就可以消除\(R^R(x)\)的影响,因为\(Q^R(x)\)的次数\(n-m<n-m+1\),所以取模并不会对\(Q^R(x)\)产生影响,所以可以求解\(Q(x)\),反带之后就可以求解\(R(x)\)

\[f^R(x)\equiv Q^R(x)g^R(x) \ \ \ (mod \ x^{n-m+1}) \]

多项式开方

问题:

给定多项式\(g(x)\),求多项式\(f(x)\),满足

\[f^2(x)\equiv g(x) \pmod{x^n} \]

解法

假设已经求出了\(g(x)\)在模\(x^{\lceil\frac n2\rceil}\)意义下的平方根\(f_0(x)\)

则有

\[f_0^2(x)\equiv g(x) \pmod{x^{\lceil\frac n2\rceil}} \\ f_0^2(x)-g(x) \equiv 0 \pmod{x^{\lceil\frac n2\rceil}} \\ (f_0^2(x))-g(x))^2\equiv 0\pmod{x^n} \\ (f_0^2(x)+g(x))^2\equiv 4f_0^2(x)g(x)\pmod{x^n} \\ (\frac{f_0^2(x)+g(x)}{2f_0(x)})^2\equiv g(x)\pmod{x^n} \\ \frac{f^2_0(x)+g(x)}{2f_0(x)}\equiv f(x) \pmod{x^n} \\ 2^{-1}f_0(x)+2^{-1}f_0^{-1}(x)g(x)\equiv f(x)\pmod{x^n} \]

递归计算即可

特征方程

一个数列\(\lbrace x_i\rbrace\) 存在递推式\(x_{n+2}=c_1x_{n+1}+c_2x_{n}\)

设有\(r,s\),使得

\[x_{n+2}-rx_{n+1}=s(x_{n+1}-rx_n) \]

那么

\[x_{n+2}=(s+r)x_{n+1}+(-sr)x_n \]

于是有

\[\begin{cases} c_1=s+r \\ c_2=-sr \end{cases} \]

韦达定理构造方程得

\[x^2-c_1x-c_2=0 \]

这样解出\(x\)的两根即为\(s,r\),进而可以求解\(c_1,c_2\)

特征方程在一阶线性递推中的应用

设数列\(\lbrace a_i\rbrace\)的递推公式为

\[a_{i}=pa_{i-1}+q \]

\[a_i-t=p(a_{i-1}-t) \\a_i=pa_{i-1}-pt+t \]

那么

\[q=-pt+t \]

\(t\)解出代入上式,利用等比数列求和得出数列的通项公式

常系数齐次线性递推

问题

给定一个线性递推数列

\[\lbrace f_i \rbrace \]

的前\(k\)\(f_0\cdots f_{k-1}\)和其递推式\(f_n=\sum_{i=1}^ka_if_{n-i}\)的各项系数\(a_i\),求\(f_n\)

矩阵快速幂做法

我们构造它的初始矩阵为

\[A= \begin{bmatrix} {f_0}&{f_1}&{f_2}&{\cdots}&{f_{k-1}} \end{bmatrix} \]

加速矩阵为

\[B= \begin{bmatrix} {0}&{0}&{0}&{\cdots}&{0}&{a_1} \\{1}&{0}&{0}&{\cdots}&{0}&{a_2} \\{0}&{1}&{0}&{\cdots}&{0}&{a_3} \\{\vdots}&{\vdots}&{\vdots}&{\ddots}&{0}&{a_{k-1}} \\{0}&{0}&{0}&{\cdots}&{1}&{a_k} \end{bmatrix} \]

由此,时间复杂度为\(O(k^3\log n)\)

瓶颈在于如何快速求出加速矩阵\(A^{n-k+1}\)

为了解决这个问题,我们可以引出常系数齐次线性递推

先介绍一些前置知识

特征值与特征向量

矩阵乘上列向量仍然是一个列向量

若对于矩阵\(A\),存在一个列向量\(\vec v\)和一个常数\(\lambda\),使得

\[A\vec v=\lambda\vec v \]

那么称\(\vec v\)为矩阵\(A\)的特征向量,\(\lambda\)为矩阵\(A\)的特征值,上面那个方程称为矩阵\(A\)的特征方程

\(\vec v\)为初始矩阵,\(A\)为加速矩阵,那么有方程

\[\begin{bmatrix} {a_1}&{a_2}&{a_3}&{\cdots}&{a_{k-1}}&{a_k} \\{0}&{0}&{0}&{\cdots}&{0}&{1} \\{0}&{0}&{0}&{\cdots}&{1}&{0} \\{\vdots}&{\vdots}&{\vdots}&{\ddots}&{\vdots}&{\vdots} \\{0}&{1}&{0}&{\cdots}&{0}&{0} \end{bmatrix} \times \begin{bmatrix} {f_k}\\{f_{k-1}}\\f_{k-2}\\\vdots\\f_{1} \end{bmatrix} = \begin{bmatrix} {f_k+1}\\{f_{k}}\\f_{k-1}\\\vdots\\f_{2} \end{bmatrix} =\lambda\vec v= \begin{bmatrix} {\lambda f_k}\\{\lambda f_{k-1}}\\\lambda f_{k-2}\\\vdots\\\lambda f_{1} \end{bmatrix} \]

发现

\[f_i=\lambda f_{i-1}=\lambda ^2 f_{i-2}=\cdots=\lambda ^{i-1} f_1 \]

又因为

\[f_{k+1}=a_1f_k+a_2f_{k-1}+\cdots+a_kf_{1} \]

\(f_i\)全部换成\(f_1\)

那么有

\[\lambda^kf_1=a_1\lambda ^{k-1}f_1+a_2\lambda ^{k-2}f_1+\cdots+a_k\lambda ^0f_1 \\\lambda^k=a_1\lambda ^{k-1}+a_2\lambda ^{k-2}+\cdots+a_k\lambda ^0 \\\lambda^k-a_1\lambda ^{k-1}-a_2\lambda ^{k-2}-\cdots-a_k\lambda ^0=0 \]

我们设

\[\varphi(x)=\lambda^k-a_1\lambda ^{k-1}-a_2\lambda ^{k-2}-\cdots-a_k\lambda ^0 \]

写高级点

\[\varphi(x)=\lambda ^k-\sum_{i=1}^ka_i\lambda^{k-i} \]

此时称\(\varphi(x)\)为矩阵\(A\)的特征多项式

它也可以这样表示

\[A\vec v=\lambda\vec v \\(A-I\lambda)\vec v=0 \]

特征多项式

\[\varphi(x)=\mid A-I\lambda\mid \]

考虑当\(x=A\),有

\[\varphi(A)=\mid A-IA\mid=0 \]

即对于矩阵\(A\)的特征多项式\(\varphi(x)\),有\(\varphi(A)=0\),这被称为\(Cayley-Hamilton定理\)

常系数齐次线性递推

前置知识说完了,考虑我们原先的问题

如何快速求出\(A^{n-k+1}\)

我们将问题简化为求\(A^n\),这与上面那个问题在规模上是等价的

考虑多项式除法/取模

\[x^n=\varphi(x)g(x)+r(x) \]

其中\(g(x),r(x)\)为两个多项式,此时我们可以利用前面学到的多项式取模求得\(r(x)\),但这有什么用呢?

将其改为矩阵的形式

\[A^n=\varphi(A)g(A)+r(A) \]

\(Cayley-Hamilton定理\)可知,\(\varphi(A)=0\)

那么有

\[A^n=r(x) \]

由多项式取模的定义,\(\deg (r(x))< k\),复杂度有了保证

所以我们把原来的矩阵\(A\)带入求出的多项式\(r(x)\),设它为

\[r(x)=\sum_{i=0}^{k-1}c_ix^i \]

我们在两边乘上\(\vec v\),然后推导

\[r(A)\vec v\sum_{i=0}^{k-1}c_iA^i\vec v_0 \\A^{n-k+1}\vec v_0=\sum_{i=0}^{k-1}c_iA^i\vec v_0 \\\vec v_n=\sum_{i=0}^{k-1}c_i\vec v_i \]

然后,终于做完了!

posted on 2022-08-05 08:34  star_road_xyz  阅读(114)  评论(0编辑  收藏  举报

导航