- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
深入探究多项式乘法的快速算法
焦作市第一中学闵梓轩
高精度、多项式与生成函数
1.1高精度
在OI中我们有时会碰到一些问题的必要数值超出64位整形的范围,这个时候我们就需要用到高精度方式存储。而高精度数的思想是进制思想的一个具体体现,出于正常人类的习惯,我们所使用的高精度数都采用10进制,即每一位都表示十进制上的一个数,从0~9,更进一步,为了优化高精度数运算所花费的时间与空间,我们采用了万进制,即每一位存0~9999的数,这样同时优化了程序效率,同时在输出上也没有什么太大的问题(每一位不足1000补0即可)。
当然,我们也可以用三进制、五进制、450进制,8964进制的高精度数,虽然因为在输出时会变得非常麻烦而没有人去用,但是它们的可行性正对应了进制的一种思想,比如一个十进制数12450,它的算数含义是二进制数10010,它的算数含义是(把为0的位忽略),这样形如的每一位上的数字在数值表示上都乘上了某个数的一个幂的数正是进制思想的基础。在编程实现上这样的一个数我们通常用整形数组来表示,a[i]表示i次项的系数,如果数组长度为n,那么学过高精度的人都知道两个数相加的时间复杂度是θ(n),两个数相乘的时间复杂度是O(n^2),在信息学竞赛中,这样的时间复杂度足以满足大部分题目的需求,因为一般来说我们的数值都不会达到10^100000次方这么大。
1.2多项式
熟悉数学的我们能够发现上面这样的一个式子,如果忽略了括号中的内容的限制,那么我们可以发现这样的式子其实就是我们所学的n次多项式,比如十进制数12450就是当x=10的时候的数值嘛。所以,当一个值b代入多项式A(x)时,这个式子也就变成了一个值A(b)。但是要注意的是多项式的系数是没有限制的,所以多项式可以用浮点数组表示,而且我们可以惊奇地发现多项式的加法和乘法在代码上除了不需要进位之外和高精度是一样的。所以说,我们所见的b进制数值,就是一个当x=b的多项式的取值而已。但是在多项式中,x的意义仅仅是一个符号而已,ai*x^i你可以理解为ai在数组的第i个位置。
我们需要注意的是,n次多项式的数组表示需要用到n+1个数,为什么?因为有n个含x的项和一个常数项,所以我们一般把多项式A(x)的最高次项的次数+1称作为这个多项式的次数界(次数界的真正意义是系数不为零的最高次项的次数+1,下文中提到的“次数界“为了更清晰的算法表述,将其定义为按需求扩展后的数组长度,此时最高次项可能是为零的。)。所以,存储一个次数界为n的多项式只需要开一个长度为n的数组就行了。
现在我们需要严格地定义多项式的运算,以下假定A、B的次数界分别为n、m:
注意D的次数界:两个次数界为n和m的多项式相乘时,积的次数界为n+m-1,D被称为A和B的卷积。
这样一来求和就是从0到n-1枚举i,将ai和bi相加的结果作为ci即可,时间复杂度θ(max(n,m))。求积就是从0到n-1两层枚举i和j,将ai和bj相乘的结果加到d(i+k)上,时间复杂度θ(nm)。说白了就是不用进位的高精度乘法。
1.3生成函数
然而多项式在OI中有什么用呢?好像除了高精度之外没有什么卵用。但是熟悉组合数学的小伙伴们会了解一个叫做生成函数的东西,生成函数是什么呢?是,看到了木有,和多项式简直一模一样,而且如果把∞换成n,那这个式子不就真的变成多项式了吗?在组合数学中,数列A的生成函数的i次项系数ai就是这个数列的第i项。然而我们在生成函数解决问题时是用得到乘法的,有人可能会说这TM有无穷项你乘个卵?但是我们真正关心的没有那么多项,比如我们可能会只关注这个数列的第n项,这个时候第n+1项以及往后的数值我们就没有必要再乘了(相当于对x^(n+1)取模,同余原理懂吧?懂吧?就像组合计数时要求你对一个大质数取模避免高精度一样),这个时候,生成函数的乘法就变成了多项式乘法!O(n^2)的乘法或许对于高精度来说足够了,但是对于只需要算常数次乘法,并且只关心其中一项的生成函数来说,你需要计算的,可能有很多位。比如我们需要计算一个一个数列的第n项,也就是这个数列生成函数的第n位,那么如果当n=300000的时候你的乘法就会瞬间爆炸,那么,有没有更快的算法呢?
二、分而治之
分治思想对于计算机科学而言就像心脏,而数组这样的形式是很容易引起我们的分治欲望的,我们不如来看看是否能够通过对数组进行分治而来实现优化。
2.1裂项相乘
对于数组来说,最基本的分治就是从中分开了,一般的数组分治就是取左端点右端点加起来除以二省略余数作为分治的界限,但是如果数组的长度正好是偶数的话思路分治算法会更加方便一些,直接从中间分开就行了,两边长度一样的。
我们注意到,生成函数如果只有有限项不为0的话,那么它就是多项式,如果我们反过来想,这个性质就变成
原创力文档


文档评论(0)