[BZOJ2179]FFT快速傅立叶
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
HINT
n<=60000
Solution
今天终于把数论版的弄好了。之前好像是因为1LL没加调不出来。
觉得压4位会快很多,但是Wa了半天,不管了。。。
1 /************************************************************** 2 Problem: 2179 3 User: wjy1998 4 Language: C++ 5 Result: Accepted 6 Time:656 ms 7 Memory:19848 kb 8 ****************************************************************/ 9 10 #include<cstdio> 11 #include<cmath> 12 #include<cstring> 13 const double PI=acos(-1); 14 struct P{double x,y;}; 15 P operator+(const P&a,const P&b){return (P){a.x+b.x,a.y+b.y};} 16 P operator-(const P&a,const P&b){return (P){a.x-b.x,a.y-b.y};} 17 P operator*(const P&a,const P&b){double d=a.x*b.x,e=a.y*b.y,f=(a.x+a.y)*(b.x+b.y);return (P){d-e,f-e-d};} 18 19 int a[270000],b[270000],n,m,k; 20 P w[2][270000],x[270000],y[270000]; 21 void FFT(P*x,int k,int v) 22 { 23 int i,j,l;P tmp; 24 for(i=j=0;i<k;i++) 25 { 26 if(i>j)tmp=x[i],x[i]=x[j],x[j]=tmp; 27 for(l=k>>1;(j^=l)<l;l>>=1); 28 } 29 for(i=2;i<=k;i<<=1) 30 for(j=0;j<k;j+=i) 31 for(l=0;l<i>>1;l++) 32 { 33 tmp=x[j+l+(i>>1)]*w[v][k/i*l]; 34 x[j+l+(i>>1)]=x[j+l]-tmp; 35 x[j+l]=x[j+l]+tmp; 36 } 37 } 38 char s[60010]; 39 void gett(int*c) 40 { 41 scanf("%s",s);int i,len=strlen(s);m=(len+1)/2; 42 for(i=0;i<len;i++)c[(len-1-i)/2]=c[(len-1-i)/2]*10+s[i]-'0'; 43 } 44 45 int main(){ 46 scanf("%d",&n);int i,j;m=n>>1;gett(a);gett(b); 47 n=m;for(k=1;k<n<<1;k<<=1); 48 for(i=0;i<=k;i++)w[1][k-i]=w[0][i]=(P){cos(PI*2*i/k),sin(PI*2*i/k)}; 49 for(i=0;i<k;i++)x[i]=(P){a[i],0};FFT(x,k,0); 50 for(i=0;i<k;i++)y[i]=(P){b[i],0};FFT(y,k,0); 51 for(i=0;i<k;i++)x[i]=x[i]*y[i];FFT(x,k,1); 52 for(i=0;i<2*k;i++)a[i]=(int)(x[i].x/k+0.5); 53 for(i=0;i<2*k-1;i++) 54 a[i+1]+=a[i]/100,a[i]%=100; 55 k=2*k-1;while(!a[k])k--; 56 printf("%d",a[k]); 57 for(i=k-1;~i;i--)printf("%02d",a[i]); 58 }