题意:求高精度A*B
思路:把A和B的每一位用多项式系数来表示,然后就可以用FFT来加速
#include<bits/stdc++.h>
#define pi acos(-1)
#define maxn 222222
using namespace std;
struct plex { ///定义一个复数类
double x, y;
plex (double _x = 0.0, double _y = 0.0) : x (_x), y (_y) {}
plex operator + (const plex &a) const {
return plex (x+a.x, y+a.y);
}
plex operator - (const plex &a) const {
return plex (x-a.x, y-a.y);
}
plex operator * (const plex &a) const {
return plex (x*a.x-y*a.y, x*a.y+y*a.x);
}
};
void change (plex *y, int len) {
int i, j, k;
for(i = 1, j = len / 2; i < len - 1; i++) {
if (i < j) swap(y[i], y[j]);
k = len / 2;
while (j >= k) {
j -= k;
k /= 2;
}
if (j < k) j += k;
}
}
void fft(plex y[],int len,int on)
{
change(y,len);
for(int h = 2; h <= len; h <<= 1)
{
plex wn(cos(-on*2*pi/h),sin(-on*2*pi/h)); ///根据欧拉公式求wn
for(int j = 0;j < len;j+=h)
{
plex w(1,0);
for(int k = j;k < j+h/2;k++)
{
plex u = y[k];
plex t = w*y[k+h/2];
y[k] = u+t;
y[k+h/2] = u-t;
w = w*wn;
}
}
}
if(on == -1) ///看是dft还是idft
for(int i = 0;i < len;i++)
y[i].x /= len;
}
char s1[maxn],s2[maxn];
plex x1[maxn],x2[maxn];
int ans[maxn];
int main()
{
while(scanf("%s%s",s1,s2)!=EOF) {
int len=1;
int l1=strlen(s1);
int l2=strlen(s2);
while(len<l1*2||len<l2*2) len<<=1;
for(int i=0;i<l1;i++) {
x1[i]=plex(s1[l1-i-1]-'0',0);
}
for(int i=l1;i<len;i++) {
x1[i]=plex(0,0);
}
for(int i=0;i<l2;i++) {
x2[i]=plex(s2[l2-i-1]-'0',0);
}
for(int i=l2;i<len;i++) {
x2[i]=plex(0,0);
}
fft(x1,len,1);
fft(x2,len,1);
for(int i=0;i<len;i++)
x1[i]=x1[i]*x2[i];
fft(x1,len,-1);
for(int i=0;i<len;i++) {
ans[i]=(int)(x1[i].x+0.5);
}
for(int i=0;i<len;i++) {
if(ans[i]>=10) {
ans[i+1]+=ans[i]/10;
ans[i]%=10;
}
}
len=l1+l2-1;
while(ans[len]==0&&len>0) len--;
for(int i=len;i>=0;i--) {
printf("%d",ans[i]);
}
printf("\n");
}
return 0;
}