任意类型多项式乘法
前言
所谓“任意类型”,事实上指的是一种代数结构 ,满足:
- ,且 构成阿贝尔群。
- 。
- 。
即,元素集合 上定义了加法和乘法,加法满足交换律,乘法不需要满足结合律,满足分配律。也就是说, 是不需要满足乘法结合律的环。
于是,我们有一种算法,可以计算 上的乘法。
在实际应用中, 可以是几乎任何你能想到的东西:模 ,模 ,模 ,也可以是矩阵甚至是四元数,或者你自己随便定义的东西。
前置知识
定义与记号
我们会用到抽象代数中的一些概念,但是我们不需要知道严谨的定义,只需要一个相对感性的理解即可。
- 环(Ring)是由元素集合、加法运算、乘法运算组成的三元组 ,加法满足交换律,乘法满足分配律,加法和乘法满足结合律。事实上,在本文探讨的范围中,乘法结合律并不重要,所以乘法不满足结合律我们也将其视作环。
- 给定环 ,那么 指系数是 中元素的关于 的多项式构成的环。
- 给定环 以及 ,那么 指 中元素在“模 ”意义下运算构成的环。你不需要了解这里“模”的严谨定义,因为在本文中只会涉及多项式的取模,这是大家熟知的。
- 对于 ,我们记 为 个 相加。
单位根
因为抽象的概念难以描述,所以我们将在复数域上讨论单位根。
若 满足 ,那么称其为 次单位根。
若对于 ,那么称 为一个 次本原单位根(Primitive Root),或称原根。我们任取一个本原单位根,记作 。那么任何一个单位根都是 的幂。
若 ,那么可以发现, 是原根当且仅当 。于是我们可以得到:原根的数量是 。
分圆多项式
定义 阶分圆多项式 。即,根恰好为 个原根的多项式。
那么我们有结论:
-
次数为 ,这是显然的。
-
,证明:
因为 的根是所有 次单位根,所以 的所有根都是 的根,将多项式分解即得证。
-
,证明:
记 为 次原根组成的集合。记 ,那么,,于是每个 次单位根恰好在 中出现一次。于是结论可以得证。
-
是首一整系数多项式,证明:
首一显然,整系数考虑使用数学归纳。
-
对于 显然成立。
-
假设结论对于所有 均成立。那么,令
则根据归纳假设知 是整系数的。于是根据带余除法,有唯一的 满足:
且 是整系数的。根据上一个结论,我们有 ,所以:
根据带余除法性质,,所以 。所以 是整系数的。
于是结论得证。
-
-
是不可约的,证略。
-
对于 次原根 ,关于 的多项式的运算可以对 取模,证明:
因为 ,所以取模不会影响多项式的实际值。
该结论的一个引申结论是, 可以被唯一地被 线性表示,并且系数为整数。
Cantor's Algorithm
要进行多项式乘法,我们尝试使用 DFT。那么我们主要面对的问题有两个:
- 不存在单位根。
- IDFT 需要进行除法(即由 推出 ),我们不一定能够做除法。
接下来我们尝试逐个解决这两个问题。
规避单位根
我们采用扩域的思想,引入虚单位根 并且带着它做运算。但是这样做一次乘法复杂度就会达到 ,肯定是无法接受的。所以我们有了下面的算法。
递归计算卷积
假设我们要求 ,那么我们选取最小的 满足 。
那么我们可以将问题转化为求 ,也就是求 。因为 ,所以结果的指数不会溢出。又因为 能被 线性表示,所以得到的结果唯一(如果对 取模,就可能得到不同的实际相等的结果)。那么最终 的系数就是 的系数。
记 ,然后写下我们的算法形式:
算法形式:给定 ,在 上计算 。
令 满足 ,那么我们可以将多项式重写:
那么, 的每一项系数都是 中的元素,于是我们的问题转化成了,求 上的乘法。
我们可以做 上长度为 的 DFT 来求出这个结果,这个 DFT 具体怎么在下一段说。我们做完 DFT 后,需要将两个数组对应位置相乘,每个位置都是 中元素。这个问题符合我们的算法形式,所以可以直接递归求解。求出结果后带入 即可得到答案。
当 足够小的时候可以进行暴力卷积,可以认为是进行 次乘法。
做 上的 DFT
在这里,我们假设我们可以进行除法。
回忆一下 DFT 的过程,以 为例(其它 类似):
因为 ,所以我们可以进行转化:。我们需要进行的操作是 上的加法以及乘 ,其中后者可以看做是循环移位。于是两个操作都可以 完成。那么一次 DFT 需要进行 次加法。
当 的时候,蝴蝶变换会变得十分鬼畜,可以采用转置 FFT 的技巧省略蝴蝶变换。
时间复杂度
我们不妨把 看做常数,那么一层中 DFT 的复杂度是 。
因为 都是 的,所以我们可以得到:
- 加法次数:。
- 乘法次数:。
规避除法
假设我们要做长度为 的 DFT,且有 次单位根 。
设我们要求 ,且 系数分别为 。记 ,设 为对 做 IDFT 后未除以 的结果,那么:
令 。记 ,然后设 为对 做 IDFT 后未除以 的结果,那么:
将 联立可以得到:
设 ,那么 是一个整数,且当 为素数 的幂时 ,否则 。则:
将上式乘上这个等式,得到:
系数都是好求的,因此我们把式子简记为:
求 和 过程类似,以前者为例。选择两个不同的互素的 进行上面的操作,我们可以得到 和 的值。而 和 互素,所以可以用 exgcd 求解 。然后计算 的值就是 。
这里使用的单位根可以直接用之前造出来的单位根,也就是在 上运算。
实现细节
- 实际实现不需要一直对 取模,可以在递归过程中对 取模(也就是循环卷积),最后再对 取模。
- 在实际应用中,如果 是模域 ,那么可以不用规避除法的步骤。对于 ,可以选择 ;对于 ,可以选择 。这样 就存在逆元,可以直接除。
- 对于 ,有 。
参考资料
参考文献
-
[1] quasisphere, Fast convolution for 64-bit integers. https://codeforces.com/blog/entry/45298.
-
[2] whx1003,如何在任意代数结构上做多项式乘法。https://www.cnblogs.com/whx1003/p/16214952.html。
-
[3] 彭雨翔,Introduction to Polynomials。
参考代码
-
因为不想写 3-radix FFT 所以没有写任意模数多项式乘法。
-
Transforming Sequence,代码,提交记录。
时限很松,可以轻松通过。
本文作者:ExplodingKonjac
本文链接:https://www.cnblogs.com/ExplodingKonjac/p/17904039.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· BotSharp + MCP 三步实现智能体开发
· BotSharp 5.0 MCP:迈向更开放的AI Agent框架
· 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
· 【ESP32】两种模拟 USB 鼠标的方法
· 设计模式脉络