洛谷P1919 A*B problem 快速傅里叶变换模板 [FFT]

  题目传送门

A*B problem

题目描述

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

输入输出格式

输入格式:

 

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

 

输出格式:

 

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

 

输入输出样例

输入样例#1:
1
3
4
输出样例#1:
12

说明

数据范围:

扫描二维码关注公众号,回复: 1706650 查看本文章

n<=60000

来源:bzoj2179

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


  分析:

  之前都是拿python水过这题的。今天学懂了FFT,特地来刷一波。

  思路没什么讲的,就是FFT,不过注意前导零,还要注意有的位数上会大于10,需要处理。

  Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<iostream>
 7 #include<iomanip>
 8 using namespace std;
 9 const double pi=acos(-1.0);
10 const int N=5e5+7;
11 int n,m,L,c[N],r[N];
12 char ca[N],cb[N];
13 struct complex{
14     double x;double y;
15     complex(double xx=0,double yy=0){x=xx;y=yy;}
16 }w1[N],w2[N];
17 complex operator + (complex a,complex b){return complex(a.x+b.x,a.y+b.y);}
18 complex operator - (complex a,complex b){return complex(a.x-b.x,a.y-b.y);}
19 complex operator * (complex a,complex b){return complex(a.x*b.x-a.y*b.y,a.x*b.y+b.x*a.y);}
20 void FFT(complex *A,int flag)
21 {
22     for(int i=0;i<n;i++)
23     if(i<r[i])swap(A[i],A[r[i]]);
24     for(int i=1;i<n;i<<=1){
25         complex wn(cos(pi/i),flag*sin(pi/i));
26         for(int j=0;j<n;j+=(i<<1)){
27             complex w(1,0);
28             for(int k=0;k<i;k++,w=w*wn){
29                 complex a=A[j+k],b=w*A[i+j+k];
30                 A[j+k]=a+b,A[i+j+k]=a-b;}
31         }
32     }
33 }
34 int main()
35 {
36     scanf("%d",&n);n--;m=2*n;
37     scanf("%s",ca);
38     for(int i=0;i<=n;i++)w1[i].x=ca[n-i]-'0';
39     scanf("%s",cb);
40     for(int i=0;i<=n;i++)w2[i].x=cb[n-i]-'0';
41     for(n=1;n<=m;n<<=1)++L;
42     for(int i=0;i<n;i++)
43     r[i]=((r[i>>1]>>1)|((i&1)<<(L-1)));
44     FFT(w1,1);FFT(w2,1);
45     for(int i=0;i<=n;i++)w1[i]=w1[i]*w2[i];
46     FFT(w1,-1);
47     for(int i=0;i<=m;i++)c[i]=(int)(w1[i].x/n+0.5);
48     for(int i=0;i<=m;i++)
49     if(c[i]>=10){
50         c[i+1]+=c[i]/10;c[i]%=10;
51         if(i==m)m++;}
52     while(m>0&&c[m]==0)m--;
53     for(int i=m;i>=0;i--)printf("%d",c[i]);
54     return 0;
55 }

猜你喜欢

转载自www.cnblogs.com/cytus/p/9215645.html