[BZOJ2179]FFT快速傅立叶

Description

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

Input

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

Output

输出一行,即x*y的结果。

Sample Input

1
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 }
View Code
posted @ 2014-07-19 23:21  n+e  阅读(286)  评论(0编辑  收藏  举报