洛谷P1919 A*B problem 快速傅裏葉變換模板 [FFT]
阿新 • • 發佈:2018-06-23
sca 快速 https -o ora stream ros for AR
題目傳送門
A*B problem
題目描述
給出兩個n位10進制整數x和y,你需要計算x*y。
輸入輸出格式
輸入格式:
第一行一個正整數n。 第二行描述一個位數為n的正整數x。 第三行描述一個位數為n的正整數y。
輸出格式:
輸出一行,即x*y的結果。(註意判斷前導0)
輸入輸出樣例
輸入樣例#1:1
3
4
輸出樣例#1:12
說明
數據範圍:
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){returncomplex(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 }
洛谷P1919 A*B problem 快速傅裏葉變換模板 [FFT]