刚学完FFT,拿来连练手
题目链接:https://www.luogu.com.cn/problem/solution/P1919
解题思路:
FFT是解决多项式乘法的,想办法把数给变成多项式
比如:
有了这个处理以后,我们可以直接看出来数的乘法不就是多项式乘法吗?!
代码中有些细节问题已做出注释
代码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <complex>
using namespace std;
#define cp complex<double>
const int N = 4e6+7; //虽然题目数据是1e6,但是下面的n可能会是4e6
const double pi = acos(-1.0);
char sa[N], sb[N];
int n = 1, lena, lenb, res[N], rev[N];
cp aa[N], bb[N];
void fft(cp *a,int inv)
{
int bit = 0;
while((1<<bit)<n)bit++;
for(int i = 0; i <= n-1; i++)
{
rev[i]=(rev[i>>1]>>1|((i&1)<<(bit-1)));
if(i < rev[i]) swap(a[i],a[rev[i]]);
}
for(int mid = 1; mid < n; mid*=2)
{
cp temp(cos(pi/mid),inv*sin(pi/mid));
for(int i = 0; i < n; i+=mid*2)
{
cp omega(1,0);
for(int j = 0; j < mid; j++,omega*=temp)
{
cp x = a[i+j], y = omega*a[i+j+mid];
a[i+j] = x+y, a[i+j+mid]=x-y;
}
}
}
}
int main()
{
scanf("%s",sa);
scanf("%s",sb);
int lena = strlen(sa), lenb = strlen(sb);
while(n < lena + lenb) n*=2; //n是2的整数次幂
for(int i = 0; i < lena; i++)
aa[i].real(sa[lena - 1 - i] - '0');
for(int i = 0; i < lenb; i++)
bb[i].real(sb[lenb - 1 - i] - '0');
fft(aa, 1);
fft(bb, 1);
for(int i = 0; i < n; i++)
aa[i] *= bb[i];
fft(aa, -1);
for(int i = 0; i < n; i++) {
res[i] += (int)(aa[i].real() / n + 0.5); //注意精度
res[i + 1] += res[i] / 10;
res[i] %= 10;
}
for(int i = res[lena + lenb - 1] ? lena + lenb - 1: lena + lenb - 2; i >= 0; i--) //两个数的乘积的长度要不然是lena+lenb,要不然是lena+lenb-1
printf("%c",(char)res[i]+'0');
printf("\n");
}

京公网安备 11010502036488号