刚学完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");
}