2016-06-01 09:34:54
很久很久很久以前写的了。。。
今天又比较了一下效率,貌似手写复数要快很多。
贴一下模板:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<complex> 9 #define ll long long 10 #define N 500020 11 using namespace std; 12 int read(){ 13 int x=0,f=1;char ch=getchar(); 14 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 15 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 16 return x*f; 17 } 18 struct CD{ 19 double a,b; 20 CD(double x=0,double y=0){a=x;b=y;} 21 friend CD operator +(CD n1,CD n2){return CD(n1.a+n2.a,n1.b+n2.b);} 22 friend CD operator -(CD n1,CD n2){return CD(n1.a-n2.a,n1.b-n2.b);} 23 friend CD operator *(CD n1,CD n2){return CD(n1.a*n2.a-n1.b*n2.b,n1.a*n2.b+n1.b*n2.a);} 24 }; 25 int n,m,bit=0; 26 const long double Pi=acos(-1.0); 27 28 void FFT(CD *a,int n,int type){ 29 for(int i=0,j=0;i<n;i++) { 30 if(j>i)swap(a[i],a[j]); 31 int k=n; 32 while(j&(k >>= 1))j&=~k; 33 j|=k; 34 } 35 for(int i=1;i<=bit;i++){ 36 CD w_n(cos(2*type*Pi/(1<<i)),sin(2*type*Pi/(1<<i))); 37 for(int j=0;j<(1<<bit);j+=(1<<i)){ 38 CD w(1,0); 39 for(int k=j;k<j+(1<<(i-1));k++){ 40 CD tmp=a[k],tt=w*a[k+(1<<(i-1))]; 41 a[k]=a[k]+tt; 42 a[k+(1<<(i-1))]=tmp-tt; 43 w=w*w_n; 44 } 45 } 46 } 47 if(type<0) for(int i=0;i<(1<<bit);i++) a[i].a=(a[i].a+0.5)/(1<<bit); 48 } 49 50 CD poly1[N],poly2[N]; 51 int c[N*2]; 52 53 char ch[N]; 54 int main (){ 55 n=read(); 56 scanf("%s",ch+1); 57 for(int i=0;i<n;i++)poly1[i]=(double)(ch[n-i]-'0'); 58 scanf("%s",ch+1); 59 for(int i=0;i<n;i++)poly2[i]=(double)(ch[n-i]-'0'); 60 bit=1; 61 while(1<<bit<(n<<1))bit++; 62 n=1<<bit; 63 FFT(poly1,n,1);FFT(poly2,n,1); 64 for(int i=0;i<n;i++)poly1[i]=poly1[i]*poly2[i]; 65 FFT(poly1,n,-1); 66 int jin=0,top=0; 67 for(int i=0;i<n;i++){ 68 jin+=(int)(poly1[i].a+0.5); 69 c[++top]=jin%10; 70 jin/=10; 71 } 72 while(top&&c[top]==0) top--; 73 while(top)putchar(c[top--]+'0'); 74 return 0; 75 }
2179: FFT快速傅立叶
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2552 Solved: 1299
[Submit][Status][Discuss]
Description
给出两个n位10进制整数x和y,你需要计算x*y。
Input
第一行一个正整数n。 第二行描述一个位数为n的正整数x。 第三行描述一个位数为n的正整数y。
Output
输出一行,即x*y的结果。
Sample Input
1
3
4
3
4
Sample Output
12
数据范围:
n<=60000
数据范围:
n<=60000