p1919 A*B Problem升级版

传送门

题目

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

输入格式:

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

输出格式:

输出一行,即x*y的结果。(注意判断前导0)

数据范围:

n<=60000

分析

将数字倒序读入,即个位数是1次方系数,十位数是2次方系数,以此类推。然后进行朴素的FFT,最后答案同样也倒序输出即可,注意输出地数应截止至2次方系数,因为1次方乘1次方得到的是2次方。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define pi acos(-1.0)
#define ri register int
int n,m,len,r[2100000];
inline int read(){
      int x=0,f=1;char s=getchar();
      while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
      while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s-'0');s=getchar();}
      return x*f;
}
inline int read2(){
      int f=1;char s=getchar();
      while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
      return (s-'0')*f;
}
struct node {
      double x,y;
      node(){};
      node(double a,double b){x=a;y=b;}
}a[2100000],b[2100000];
inline node operator + (const node a,const node b){
      return node(a.x+b.x,a.y+b.y);
}
inline node operator - (const node a,const node b){
      return node(a.x-b.x,a.y-b.y);
}
inline node operator * (const node a,const node b){
      return node(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
}
inline void fft(node *a,int f){
      for(ri i=0;i<n;i++)
        if(i<r[i])
          swap(a[i],a[r[i]]);
      for(ri k=1;k<n;k<<=1){
          node wn(cos(pi/k),sin(pi/k)*f);
          for(ri i=0;i<n;i+=(k<<1)){
            node w(1,0),p,q;
            for(ri j=0;j<k;j++,w=w*wn){
                p=a[i+j],q=a[i+j+k]*w;
                a[i+j]=p+q,a[i+j+k]=p-q;
            }
        }
      }
      if(f==-1)
        for(ri i=0;i<n;i++)
          a[i].x=a[i].x/n;
}
int ans[2100000];
int main()
{     n=read();m=n;
      a[0].x=b[0].x=0;
      for(ri i=n;i>0;i--)a[i].x=read2();
      for(ri i=m;i>0;i--)b[i].x=read2();
      m+=n;
      for(n=1;n<=m;n<<=1)len++;
      for(ri i=0;i<n;i++)r[i]=((r[i>>1]>>1)|((i&1)<<(len-1)));
      fft(a,1),fft(b,1);
      for(ri i=0;i<n;i++)a[i]=a[i]*b[i];
      fft(a,-1);
      for(ri i=1;i<=m;i++)ans[i]=(int)(a[i].x+0.5);
      for(ri i=1;i<=m;i++)
         if(ans[i]>=10){
           ans[i+1]+=(ans[i]/10);
           ans[i]%=10;
         }
      int ok=0;
      for(ri i=m+1;i>1;i--){
         if(ans[i])ok=1;
         if(ok)printf("%d",ans[i]);
      }
      return 0;
}
posted @ 2018-06-14 17:21  水题收割者  阅读(166)  评论(0编辑  收藏  举报