高精度乘高精度FFT优化算法
来源:互联网 发布:业务跟踪软件 编辑:程序博客网 时间:2024/06/08 14:38
高精度乘高精度FFT优化算法
传入参数约定:传入参数均为string类型,返回值为string类型算法思想:将两个高精度乘数每个数位上的数视为多项式对应的系数,用o(n*log(n))的复杂度转成点值形式,再利用o(n)的复杂度相乘,最后对点值进行差值,用o(n*log(n))的复杂度还原成多项式的形式,即原来的形式。
算法复杂度:o(n*log(n)).
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <map>#include <queue>#include <set>#include <vector>using namespace std;#define L(x) (1 << (x))const double PI = acos(-1.0);const int Maxn = 133015;double ax[Maxn], ay[Maxn], bx[Maxn], by[Maxn];char sa[Maxn/2],sb[Maxn/2];int sum[Maxn];int x1[Maxn],x2[Maxn];int revv(int x, int bits){ int ret = 0; for (int i = 0; i < bits; i++) { ret <<= 1; ret |= x & 1; x >>= 1; } return ret;}void fft(double * a, double * b, int n, bool rev){ int bits = 0; while (1 << bits < n) ++bits; for (int i = 0; i < n; i++) { int j = revv(i, bits); if (i < j) swap(a[i], a[j]), swap(b[i], b[j]); } for (int len = 2; len <= n; len <<= 1) { int half = len >> 1; double wmx = cos(2 * PI / len), wmy = sin(2 * PI / len); if (rev) wmy = -wmy; for (int i = 0; i < n; i += len) { double wx = 1, wy = 0; for (int j = 0; j < half; j++) { double cx = a[i + j], cy = b[i + j]; double dx = a[i + j + half], dy = b[i + j + half]; double ex = dx * wx - dy * wy, ey = dx * wy + dy * wx; a[i + j] = cx + ex, b[i + j] = cy + ey; a[i + j + half] = cx - ex, b[i + j + half] = cy - ey; double wnx = wx * wmx - wy * wmy, wny = wx * wmy + wy * wmx; wx = wnx, wy = wny; } } } if (rev) { for (int i = 0; i < n; i++) a[i] /= n, b[i] /= n; }}int solve(int a[],int na,int b[],int nb,int ans[]){ int len = max(na, nb), ln; for(ln=0; L(ln)<len; ++ln); len=L(++ln); for (int i = 0; i < len ; ++i) { if (i >= na) ax[i] = 0, ay[i] =0; else ax[i] = a[i], ay[i] = 0; } fft(ax, ay, len, 0); for (int i = 0; i < len; ++i) { if (i >= nb) bx[i] = 0, by[i] = 0; else bx[i] = b[i], by[i] = 0; } fft(bx, by, len, 0); for (int i = 0; i < len; ++i) { double cx = ax[i] * bx[i] - ay[i] * by[i]; double cy = ax[i] * by[i] + ay[i] * bx[i]; ax[i] = cx, ay[i] = cy; } fft(ax, ay, len, 1); for (int i = 0; i < len; ++i) ans[i] = (int)(ax[i] + 0.5); return len;}string mul(string sa,string sb){ int l1,l2,l; int i; string ans; memset(sum, 0, sizeof(sum)); l1 = sa.size(); l2 = sb.size(); for(i = 0; i < l1; i++) x1[i] = sa[l1 - i - 1]-'0'; for(i = 0; i < l2; i++) x2[i] = sb[l2-i-1]-'0'; l = solve(x1, l1, x2, l2, sum); for(i = 0; i<l || sum[i] >= 10; i++) // 进位 { sum[i + 1] += sum[i] / 10; sum[i] %= 10; } l = i; while(sum[l] <= 0 && l>0) l--; // 检索最高位 for(i = l; i >= 0; i--) ans+=sum[i] + '0'; // 倒序输出 return ans;}int main(){ cin.sync_with_stdio(false); string a,b; while(cin>>a>>b) cout<<mul(a,b)<<endl; return 0;}
1 0
- 高精度乘高精度FFT优化算法
- 【高精度 乘】
- 【BZOJ2179】FFT快速傅立叶 高精度乘模板题
- 高精度计算(高精度乘高精度,高精度减高精度)
- 高精度乘法FFT 模板
- FFT 高精度乘法
- 高精度乘法 FFT
- hihocoder-1388-高精度fft
- 高精度加减乘模版
- 高精度加减乘运算
- 高精度 加 减 乘
- 高精度乘单精度
- 【模板】高精度--加减乘
- 高精度(加减乘)改
- [复习]高精度 高精度加/减/乘/除法
- 高精度算法
- 高精度算法
- 高精度算法
- 动画抖动 解决
- HDU1166-敌兵布阵
- hdu1205(基础)
- 端口被占用解决
- 链表中环的入口结点
- 高精度乘高精度FFT优化算法
- A 走廊两边搬桌子
- 关于单片机的学习经验
- [CodeForces] 510 C Fox And Names [拓扑排序]
- 一步一步教你实现Periscope点赞效果
- Java到底是值传递还是引用传递
- 构建乘积数组
- CSS3布局相关样式学习
- Java transient关键字使用小记