多项式乘积本质是卷积,即结果第k项系数为∑aᵢ×bⱼ(i+j==k);用std::vector存系数时需预分配大小为a.size()+b.size()-1,双层循环累加到result[i+j],避免push_back导致索引错位。

用 std::vector 存储系数,手动实现乘法逻辑最直接
多项式乘积本质是卷积:若 A(x) = a₀ + a₁x + ... + aₙxⁿ,B(x) = b₀ + b₁x + ... + bₘxᵐ,则结果的第 k 项系数为 ∑ aᵢ × bⱼ(其中 i + j == k)。C++ 没有内置多项式类型,所以用 std::vector<double></double> 或 std::vector<int></int> 存系数(下标即幂次)最稳妥。
常见错误是忽略结果长度——两个长度为 n+1 和 m+1 的向量相乘,结果长度应为 n + m + 1,不是 max(n, m) + 1。初始化时必须清零,否则残留值会污染结果。
- 结果向量大小设为
A.size() + B.size() - 1 - 双层循环:外层遍历
A索引i,内层遍历B索引j,累加到result[i + j] - 别用
push_back动态扩展——会导致索引错位;必须预分配并用下标赋值
用 std::valarray 能简化但不推荐用于生产
std::valarray 支持广播运算和切片,理论上可模拟卷积,比如用 shift 和逐元素乘加。但实际中问题明显:
-
valarray在 C++20 后已被标记为“可能弃用”,主流项目基本不用 - 没有原生卷积函数,仍需手写循环或嵌套
apply,可读性反而更差 - 调试困难:报错信息常指向内部模板,而非你的逻辑位置
除非在极受限嵌入式环境且编译器不支持 vector,否则跳过它。
遇到高精度或大系数,别硬刚 int/double
如果系数可能溢出(比如 100 项多项式乘积后系数超 2³¹),或需要精确整数除法、模运算,long long 也撑不住。这时要换类型:
- 用
__int128(GCC/Clang 支持)临时过渡,但不可跨平台 - 上
boost::multiprecision::cpp_int——真正任意精度,且 API 接近原生整数 - 若只需模
M(如 NTT 场景),全程用int配合% M,避免中间溢出
注意:double 会丢失整数精度(>2⁵³ 后无法表示所有整数),哪怕系数当前看着小,乘积过程也可能越界。
想加速?先确认瓶颈再上 FFT
朴素算法时间复杂度 O(nm),对几千项以内完全够用。真要优化,得看场景:
- 系数是整数且规模 ≥ 10⁴ 项?考虑
NTT(数论变换),比 FFT 更稳,无浮点误差 - 已有 FFT 库(如 FFTW)且接受浮点误差?可用复数 FFT,但最后要四舍五入取整
- 别自己手写 FFT——边界条件(逆变换缩放、位逆序重排)极易出错,且现代 CPU 上
O(n²)对n 反而更快
实际项目里,90% 的多项式乘法根本用不到 FFT。先跑个 std::chrono 测下朴素版本耗时,再决定要不要动。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











