[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

转载于:https://www.cnblogs.com/Trinkle/p/3855627.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值