洛谷P1919 模板A*B Problem升级版(FFT快速傅里叶)

Posted 自为

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1919 模板A*B Problem升级版(FFT快速傅里叶)相关的知识,希望对你有一定的参考价值。

题目描述

给出两个n位10进制整数x和y,你需要计算x*y。

输入输出格式

输入格式:

 

第一行一个正整数n。 第二行描述一个位数为n的正整数x。 第三行描述一个位数为n的正整数y。

 

输出格式:

 

输出一行,即x*y的结果。(注意判断前导0)

 

输入输出样例

输出样例#1: 复制
12

说明

数据范围:

n<=60000

来源:bzoj2179

本题数据为洛谷自造数据,使用CYaRon耗时5分钟完成数据制作。

 

emmmm感觉学了FFT没什么乱用啊,,

也就来水一水这种板子吧。

思路很简单,将每一位看成多项式的系数。

来一遍FFT

最后去掉前导0

输出

不过话说我的FFT怎么这么慢

 

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int MAXN=1e5+10;
const double Pi=acos(-1.0);
int r[MAXN],l=0,limit=1,c[MAXN];
char sa[MAXN],sb[MAXN];
struct complex
{
    double x,y;
    complex(double xx=0,double yy=0){x=xx,y=yy;}
}a[MAXN],b[MAXN];
complex operator + (complex a,complex b){return complex(a.x+b.x,a.y+b.y);}
complex operator - (complex a,complex b){return complex(a.x-b.x,a.y-b.y);}
complex operator * (complex a,complex b){return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
void FFT(complex *a,int type)
{
    for(int i=0;i<limit;i++)
        if(i<r[i]) 
            swap(a[i],a[r[i]]);
    for(int mid=1;mid<limit;mid<<=1)
    {
        complex Wn(cos(Pi/mid),type*sin(Pi/mid) );
        for(int R=mid<<1,j=0;j<limit;j+=R)
        {
            complex w(1,0);
            for(int k=0;k<mid;k++,w=w*Wn)
            {
                complex x=a[j+k],y=w*a[j+k+mid];
                a[j+k]=x+y;
                a[j+k+mid]=x-y;
            }
        }
    }
}
int main()
{
    #ifdef WIN32
    freopen("a.in","r",stdin);
    #else 
    #endif
    int N;
    scanf("%d",&N);N--;
    scanf("%s%s",sa,sb);
    for(int i=0;i<=N;i++) a[i].x=sa[N-i]-0,b[i].x=sb[N-i]-0;
    while(limit<=N*2) 
        limit<<=1,l++;
    for(int i=0;i<=limit;i++) r[i]=(r[i>>1]>>1) | ((i&1)<<(l-1) );
    FFT(a,1);
    FFT(b,1);
    for(int i=0;i<=limit;i++) a[i]=a[i]*b[i];
    FFT(a,-1);
    for(int i=0;i<=limit;i++) c[i]=(int)(a[i].x/limit+0.5);
    //for(int i=1;i<=limit;i++) printf("%d ",c[i]);printf("\n");
    for(int i=0;i<=limit;i++)
    {
        if(c[i]>10)
        {
            c[i+1]+=c[i]/10,c[i]%=10;
            if(i+1>limit) limit++;
        }
    }
    for(int i=limit;i>=0;i--)
        if(c[i]==0) limit--;
        else break;
    for(int i=limit;i>=0;i--)
        printf("%d",c[i]);
    return 0;
}

 

以上是关于洛谷P1919 模板A*B Problem升级版(FFT快速傅里叶)的主要内容,如果未能解决你的问题,请参考以下文章

P1919 模板A*B Problem升级版(FFT快速傅里叶)

luogu P1919 模板A*B Problem升级版(FFT快速傅里叶)

luogu P1919 模板A*B Problem升级版(FFT快速傅里叶)|FFT

洛谷.1919.[模板]A乘B Problem升级版(FFT)

洛谷 P1581 A+B Problem(升级版)

洛谷——P1832 A+B Problem(再升级)