当前位置: 首页 > news >正文

MIT-两个多项式相乘

文章目录

  • 问题描述
  • 算法实现
    • 暴力算法
    • 分治算法
    • Karatsuba(优化的分治算法)

问题描述

给定两个次数为 nnn 的多项式:

A(x)=a0+a1x+⋯+anxnB(x)=b0+b1x+⋯+bnxn\begin{gathered}A(x)=a_0+a_1x+\cdots+a_nx^n\\B(x)=b_0+b_1x+\cdots+b_nx^n\end{gathered}A(x)=a0+a1x++anxnB(x)=b0+b1x++bnxn

求它们的积 A(x)⋅B(x)A(x)\cdot B(x)A(x)B(x)


算法实现

暴力算法

我们设 A(x)=∑i=0naixiA(x)=\sum_{i=0}^{n}a_{i}x^{i}A(x)=i=0naixiB(x)=∑i=0nbixiB(x)=\sum_{i=0}^{n}b_{i}x^{i}B(x)=i=0nbixiC(x)=∑k=02ncixi=A(x)B(x)C(x)=\sum_{k=0}^{2n}c_{i}x^{i}=A(x)B(x)C(x)=k=02ncixi=A(x)B(x)。其中 ck=∑i=0kaibk−ic_k=\sum_{i=0}^ka_ib_{k-i}ck=i=0kaibki0≤k≤2n0\leq k\leq 2n0k2n

int* Brute_PolynomialMultiply(int a[], int b[], int n)
{int m = 2 * n;int c[m];for (int k = 0; k <= m; k ++ ){for (int i = 0; i <= k; i ++ )c[k] += a[i] * b[k - i];}return c;
}

时间复杂度 :O(n2)O(n^2)O(n2)


分治算法

考虑到多项式乘法问题的结构性质,我们可以采用分治算法。该算法的核心思想是将大问题分解为多个较小的子问题,利用分治策略递归地解决这些子问题,从而减少计算量

在多项式乘法中,我们可以将每个多项式分解为两部分,并递归地计算这些部分的乘积。具体来说,我们定义
A0(x)=a0+a1x+⋯+a⌊n2⌋−1x⌊n2⌋−1,A1(x)=a⌊n2⌋+a⌊n2⌋+1x+⋯+anxn−⌊n2⌋.\begin{array}{rcl}A_0(x)&=&a_0+a_1x+\cdots+a_{\lfloor\frac{n}{2}\rfloor-1}x^{\lfloor\frac{n}{2}\rfloor-1},\\A_1(x)&=&a_{\lfloor\frac{n}{2}\rfloor}+a_{\lfloor\frac{n}{2}\rfloor+1}x+\cdots+a_nx^{n-\lfloor\frac{n}{2}\rfloor}.\end{array}A0(x)A1(x)==a0+a1x++a2n1x2n1,a2n+a2n+1x++anxn2n.

多项式A(x)A(x)A(x) 可写成 A(x)=A0(x)+xn/2A1(x)A(x)=A_0(x)+x^{n/2}A_1(x)A(x)=A0(x)+xn/2A1(x) 的形式 。

同样的,我们也可以像上述一样定义 B0(x)B_0(x)B0(x)B1(x)B_1(x)B1(x),多项式 B(x)B(x)B(x) 可写成下面的形式:

B(x)=B0(x)+B1(x)x⌊n2⌋B(x)=B_{0}(x)+B_{1}(x)x^{\lfloor\frac{n}{2}\rfloor}B(x)=B0(x)+B1(x)x2n

所以,我们可以通过以下方式计算它们的乘积:

A(x)B(x)=A0(x)B0(x)+A0(x)B1(x)x⌊n2⌋+A1(x)B0(x)x⌊n2⌋+A1(x)B1(x)x2⌊n2⌋A(x)B(x)=A_{0}(x)B_{0}(x)+A_{0}(x)B_{1}(x)x^{\lfloor\frac{n}{2}\rfloor}+A_{1}(x)B_{0}(x)x^{\lfloor\frac{n}{2}\rfloor}+A_{1}(x)B_{1}(x)x^{2\lfloor\frac{n}{2}\rfloor}A(x)B(x)=A0(x)B0(x)+A0(x)B1(x)x2n+A1(x)B0(x)x2n+A1(x)B1(x)x22n

这样就将原来问题规模为 nnn 的问题分割成 444n2\frac{n}{2}2n 的子问题了,分别为:
U(x)=A0(x)B0(x),V(x)=A0(x)B1(x),W(x)=A1(x)B0(x),Z(x)=A1(x)B1(x)\begin{array}{cc}U(x)=A_0(x)B_0(x),&V(x)=A_0(x)B_1(x),\\W(x)=A_1(x)B_0(x),&Z(x)=A_1(x)B_1(x)\end{array}U(x)=A0(x)B0(x),W(x)=A1(x)B0(x),V(x)=A0(x)B1(x),Z(x)=A1(x)B1(x)

在这里插入图片描述

// 多项式相加
vector<int> addPoly(const vector<int>& A, const vector<int>& B) {int n = max(A.size(), B.size());vector<int> result(n, 0);for (int i = 0; i < n; i++) {if (i < A.size()) result[i] += A[i];if (i < B.size()) result[i] += B[i];}return result;
}vector<int> DC_multiplyPoly(const vector<int>& A, const vector<int>& B) {int n = A.size();// 基本情况if (A.empty() || B.empty()) return {};if (n == 1) return {A[0] * B[0]};int mid = n / 2;// 分割多项式vector<int> A0(A.begin(), A.begin() + mid);  // [0, mid - 1)vector<int> A1(A.begin() + mid, A.end()); //vector<int> B0(B.begin(), B.begin() + mid);vector<int> B1(B.begin() + mid, B.end());// 递归计算vector<int> U = DC_multiplyPoly(A0, B0);vector<int> V = DC_multiplyPoly(A0, B1);vector<int> W = DC_multiplyPoly(A1, B0);vector<int> Z = DC_multiplyPoly(A1, B1);// 假设P0 = V(x) + W(x)vector<int> P0 = addPoly(V, W);// 合并结果vector<int> result(2 * n, 0);for (int i = 0; i < U.size(); i ++ ) result[i] += U[i];for (int i = 0; i < P0.size(); i ++ ) result[i + mid] += P0[i];for (int i = 0; i < Z.size(); i ++ ) result[i + 2 * mid] += Z[i];return result;
}

时间复杂度O(n2)O(n^2)O(n2)

假设 n=2hn=2^hn=2hT(1)=O(1)T(1)=O(1)T(1)=O(1)T(n)T(n)T(n) 是执行一次两个多项式均为 nnn 次的DC_multiplyPoly所需的时间。

  • vector<int> U = DC_multiplyPoly(A0, B0)T(n2)T(\frac{n}{2})T(2n)
  • vector<int> V = DC_multiplyPoly(A0, B1)T(n2)T(\frac{n}{2})T(2n)
  • vector<int> W = DC_multiplyPoly(A1, B0)T(n2)T(\frac{n}{2})T(2n)
  • vector<int> Z = DC_multiplyPoly(A1, B1)T(n2)T(\frac{n}{2})T(2n)
  • vector<int> P0 = addPoly(V, W)O(n)O(n)O(n)
  • for (int i = 0; i < Z.size(); i ++ ) result[i + 2 * mid] += Z[i]O(n)O(n)O(n)
  • vector<int> A0(A.begin(), A.begin() + mid)O(1)O(1)O(1)
  • vector<int> B1(B.begin() + mid, B.end())O(1)O(1)O(1)

Tn=4T(n2)+cn+O(n)=4[4T(n22)+cn2+O(n2)]+cn+O(n)=42T(n22)+(1+2)cn+O(n)=42[4T(n23)+cn22+O(n22)]+(1+2)cn+O(n)=43T(n23)+(1+2+22)cn+O(n)=...=4iT(n2i)+∑j=0i−12jcn+O(n)=...=4hT(n2h)+∑j=0h−12jcn+O(n)=(2h)2T(1)+1⋅(1−2h)1−2cn+O(n)=n2T(1)+cn(n−1)+O(n)=O(n2)+cn2−cn+O(n)=O(n2)\begin{aligned} T_n&=4T(\frac{n}{2})+cn+O(n) \\&= 4\left[4T\left(\frac{n}{2^2}\right)+c\frac{n}{2}+O(\frac{n}{2})\right]+cn+O(n) \\ & = 4^2T\left(\frac{n}{2^2}\right)+(1+2)cn +O(n) \\ & =4^2\left[4T\left(\frac{n}{2^3}\right)+c\frac{n}{2^2} + O(\frac{n}{2^2})\right]+(1+2)cn+O(n) \\ & = 4^3T\left(\frac{n}{2^3}\right)+(1+2+2^2)cn + O(n) \\ &= ... \\& = 4^iT\left(\frac{n}{2^i}\right)+\sum_{j=0}^{i-1}2^jcn +O(n) \\&= ... \\& = 4^hT\left(\frac{n}{2^h}\right)+\sum_{j=0}^{h-1}2^jcn +O(n) \\&= (2^h)^2T(1)+\frac{1\cdot(1-2^h)}{1-2}cn + O(n) \\&=n^2T(1)+cn(n-1) + O(n) \\&= O(n^2)+cn^2-cn+O(n) \\&=O(n^2) \end{aligned}Tn=4T(2n)+cn+O(n)=4[4T(22n)+c2n+O(2n)]+cn+O(n)=42T(22n)+(1+2)cn+O(n)=42[4T(23n)+c22n+O(22n)]+(1+2)cn+O(n)=43T(23n)+(1+2+22)cn+O(n)=...=4iT(2in)+j=0i12jcn+O(n)=...=4hT(2hn)+j=0h12jcn+O(n)=(2h)2T(1)+121(12h)cn+O(n)=n2T(1)+cn(n1)+O(n)=O(n2)+cn2cn+O(n)=O(n2)


Karatsuba(优化的分治算法)

由上述的基础分治算法可以知道 A(x)B(x)A(x)B(x)A(x)B(x) 多项式乘积的形式为:

A(x)B(x)=A0(x)B0(x)+[A0(x)B1(x)+A1(x)B0(x)]xn2+A1(x)B1(x)x2⌊n2⌋A(x)B(x)=A_{0}(x)B_{0}(x)+[A_{0}(x)B_{1}(x) + A_{1}(x)B_{0}(x)]x^{\frac{n}{2}}+A_{1}(x)B_{1}(x)x^{2\lfloor\frac{n}{2}\rfloor}A(x)B(x)=A0(x)B0(x)+[A0(x)B1(x)+A1(x)B0(x)]x2n+A1(x)B1(x)x22n

我们在基础的分治算法的基础上,重新定义:

Y(x)=[A0(x)+A1(x)]×[B0(x)+B1(x)]U(x)=A0(x)B0(x)Z(x)=A1(x)B1(x)\begin{aligned}Y(x)&=[A_0(x)+A_1(x)]\times[B_0(x)+B_1(x)]\\U(x)&=A_0(x)B_0(x)\\Z(x)&=A_1(x)B_1(x)\end{aligned}Y(x)U(x)Z(x)=[A0(x)+A1(x)]×[B0(x)+B1(x)]=A0(x)B0(x)=A1(x)B1(x)

故有

A0(x)B1(x)+A1(x)B0(x)=Y(x)−U(x)−Z(x)A_{0}(x)B_{1}(x) + A_{1}(x)B_{0}(x)=Y(x)-U(x)-Z(x)A0(x)B1(x)+A1(x)B0(x)=Y(x)U(x)Z(x)

即最后 A(x)B(x)A(x)B(x)A(x)B(x) 的多项式为:

A(x)B(x)=U(x)+[Y(x)−U(x)−Z(x)]x⌊n2⌋+Z(x)×x2⌊n2⌋A(x)B(x)=U(x)+[Y(x)-U(x)-Z(x)]x^{\lfloor\frac{n}{2}\rfloor}+Z(x)\times x^{2\lfloor\frac{n}{2}\rfloor}A(x)B(x)=U(x)+[Y(x)U(x)Z(x)]x2n+Z(x)×x22n

我们用了一个小的数学技巧,将原本需要分割成 4 个 n2\frac{n}{2}2n 的子问题,变成了 3 个 n2\frac{n}{2}2n 个子问题。

// 多项式相减 A - B
vector<int> subPoly(const vector<int>& A, const vector<int>& B) {int n = max(A.size(), B.size());vector<int> result(n, 0);for (int i = 0; i < n; i++) {if (i < A.size()) result[i] += A[i];if (i < B.size()) result[i] -= B[i];}return result;
}vector<int> Karatsuba_multiplyPoly(const vector<int>& A, const vector<int>& B) {int n = A.size();// 基本情况if (A.empty() || B.empty()) return {};if (n == 1) return {A[0] * B[0]};int mid = n / 2;// 分割多项式vector<int> A0(A.begin(), A.begin() + mid);  // [0, mid - 1)vector<int> A1(A.begin() + mid, A.end()); //vector<int> B0(B.begin(), B.begin() + mid);vector<int> B1(B.begin() + mid, B.end());// 递归计算 修改点在这里!!!!vector<int> U = Karatsuba_multiplyPoly(A0, B0);vector<int> Z = Karatsuba_multiplyPoly(A1, B1);vector<int> Y = Karatsuba_multiplyPoly(addPoly(A0, A1), addPoly(B0, B1));// 假设P0 = Y(x) - U(x) - Z(x)P0 = subPoly(subPoly(Y, U), Z);// 合并结果vector<int> result(2 * n, 0);for (int i = 0; i < U.size(); i ++ ) result[i] += U[i];for (int i = 0; i < P0.size(); i ++ ) result[i + mid] += P0[i];for (int i = 0; i < Z.size(); i ++ ) result[i + 2 * mid] += Z[i];return result;
}

时间复杂度:O(nlog⁡23)≈O(n1.585)O(n^{\log_23})\approx O(n^{1.585})O(nlog23)O(n1.585)

假设 n=2hn=2^hn=2hT(1)=O(1)T(1)=O(1)T(1)=O(1)T(n)T(n)T(n) 是执行一次两个多项式均为 nnn 次的Karatsuba_multiplyPoly所需的时间。

  • vector<int> U = DC_multiplyPoly(A0, B0)T(n2)T(\frac{n}{2})T(2n)
  • vector<int> Z = DC_multiplyPoly(A1, B1)T(n2)T(\frac{n}{2})T(2n)
  • vector<int> Y = Karatsuba_multiplyPoly(addPoly(A0, A1), addPoly(B0, B1))T(n2)T(\frac{n}{2})T(2n)
  • addPoly(V, W)O(n)O(n)O(n)
  • subPoly(V, W)O(n)O(n)O(n)
  • for (int i = 0; i < Z.size(); i ++ ) result[i + 2 * mid] += Z[i]O(n)O(n)O(n)
  • vector<int> A0(A.begin(), A.begin() + mid)O(1)O(1)O(1)
  • vector<int> B1(B.begin() + mid, B.end())O(1)O(1)O(1)

Tn=3T(n2)+cn+O(n)=3[3T(n22)+cn2+O(n2)]+cn+O(n)=32T(n22)+(1+32)cn+O(n)=32[3T(n23)+cn22+O(n22)]+(1+32)cn+O(n)=33T(n23)+(1+32+[32]2)cn+O(n)=...=3hT(n2h)+∑j=0h−1[32]jcn+O(n)=3hT(1)+c2(3h−n)+O(n)=(2log⁡23)hT(1)+c2((2log⁡23)h−n)+O(n)=2hlog⁡23T(1)+c2(2hlog⁡23−n)+O(n)=(2h)log⁡23T(1)+c2((2h)log⁡23−n)+O(n)=O(nlog⁡23)+c2(nlog⁡23−n)+O(n)=O(nlog⁡23)\begin{aligned} T_n&=3T(\frac{n}{2})+cn+O(n) \\&= 3\left[3T\left(\frac{n}{2^2}\right)+c\frac{n}{2}+O(\frac{n}{2})\right]+cn+O(n) \\ & = 3^2T\left(\frac{n}{2^2}\right)+(1+\frac{3}{2})cn +O(n) \\ & =3^2\left[3T\left(\frac{n}{2^3}\right)+c\frac{n}{2^2} + O(\frac{n}{2^2})\right]+(1+\frac{3}{2})cn+O(n) \\ & = 3^3T\left(\frac{n}{2^3}\right)+(1+\frac{3}{2}+[\frac{3}{2}]^2)cn + O(n) \\ &= ... \\& = 3^hT\left(\frac{n}{2^h}\right)+\sum_{j=0}^{h-1}[\frac{3}{2}]^jcn +O(n) \\& = 3^hT(1)+\frac{c}{2}(3^{h}-n) + O(n) \\& = (2^{\log_2 3})^hT(1)+\frac{c}{2}((2^{\log_2 3})^h-n) + O(n) \\& = 2^{h\log_2 3}T(1)+\frac{c}{2}(2^{h\log_2 3}-n) + O(n) \\& = (2^h)^{{\log_2 3}}T(1)+\frac{c}{2}((2^h)^{{\log_2 3}}-n) + O(n) \\&=O(n^{\log_23})+\frac{c}{2}(n^{\log_23}-n) + O(n) \\&=O(n^{\log_23}) \end{aligned}Tn=3T(2n)+cn+O(n)=3[3T(22n)+c2n+O(2n)]+cn+O(n)=32T(22n)+(1+23)cn+O(n)=32[3T(23n)+c22n+O(22n)]+(1+23)cn+O(n)=33T(23n)+(1+23+[23]2)cn+O(n)=...=3hT(2hn)+j=0h1[23]jcn+O(n)=3hT(1)+2c(3hn)+O(n)=(2log23)hT(1)+2c((2log23)hn)+O(n)=2hlog23T(1)+2c(2hlog23n)+O(n)=(2h)log23T(1)+2c((2h)log23n)+O(n)=O(nlog23)+2c(nlog23n)+O(n)=O(nlog23)

http://www.dtcms.com/a/561317.html

相关文章:

  • 【每天一个AI小知识】:什么是AI Agent?
  • 547.力扣LeetCode_ 省份数量
  • Python编程实战—面向对象与进阶语法 | 属性与方法
  • 县级林业网站建设管理河南省住房和城乡建设厅电话
  • 自己怎么做返利网站中国做陶壶的网站有哪些
  • C++11新特性介绍
  • 软考 系统架构设计师系列知识点之杂项集萃(187)
  • 好用百度seo排名优化软件工具(seo快速优化软件)
  • 【SSM框架 | day24 spring IOC 与 DI】
  • .net 8.0 System.InvalidOperationException:“Session has not been configured
  • 网站关键词排名快速提升网站域名空间续费合同
  • 本地大模型、本地embeding、本地数据库、本地RAG Flow搭建方式——从显卡驱动开始
  • 10-神经网络的工作原理:分析神经网络如何学习和推理
  • 无锡做网站的公司网站业务员怎么给客户做方案
  • HarmonyOS Divider组件深度定制:从基础分割到高级视觉表达
  • 外包公司做的网站怎么改密码光辉网络 石家庄网站建设
  • 一道面试高频题:如何判断完全二叉树?
  • 使用Stream API重构你的数据处理
  • ps做网站首页怎么广州公共资源交易
  • discuz 门户网站模板物联网今天正式开网
  • python数据分析学习路线及生态
  • 【Unity踩坑】Unity测试用例命名空间错误解决方案
  • 美日股票数据API对接实战指南
  • 【Android FrameWork】第二天:认识Skia
  • 用dw做网站首页视觉营销网站建设规划分析
  • Spring Security安全框架原理与实战
  • 不用js可以做网站吗黄页88
  • 配置镜像仓库镜像(Registry Mirror)的指南
  • 25套科技商务风PPT模板合集,多场景适配专业演示(PPTX格式)
  • 网站内容收费专业网站定制报价