题目描述

这是一道模板题。

给你两个多项式,请输出乘起来后的多项式。

输入格式

第一行两个整数 $n$ 和 $m$,分别表示两个多项式的次数。

第二行 $n + 1$ 个整数,分别表示第一个多项式的 $0$ 到 $n$ 次项前的系数。

第三行 $m + 1$ 个整数,分别表示第一个多项式的 $0$ 到 $m$ 次项前的系数。

输出格式

一行 $n + m + 1$ 个整数,分别表示乘起来后的多项式的 $0$ 到 $n + m$ 次项前的系数。

限制与约定

$0 \leq n, m \leq 10^5$,保证输入中的系数大于等于 $0$ 且小于等于 $9$。

时间限制:$1\texttt{s}$

空间限制:$256\texttt{MB}$


FFT的讲解就直接链接会我原来的日志吧.....

以前公式都是图片..再写一遍就太累了QAQ

http://user.qzone.qq.com/1934784736/blog/1455871949

#include<cstdio>  
#include<iostream>  
#include<algorithm>  
#include<cstdlib>  
#include<cstring>
#include<string>
#include<climits>
#include<vector>
#include<cmath>
#include<map>
#include<set>
#include<complex>
#define LL long long
 
using namespace std;
 
inline char nc(){
  static char buf[100000],*p1=buf,*p2=buf;
  if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
  return *p1++;
}
 
inline void read(int &x){
  char c=nc();int b=1;
  for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
  for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

int wt,ss[19];
inline void print(int x){
    if (x<0) x=-x,putchar('-'); 
    if (!x) putchar(48); else {
    for (wt=0;x;ss[++wt]=x%10,x/=10);
    for (;wt;putchar(ss[wt]+48),wt--);}
}

#define pi acos(-1)
#define E complex<double>
E a[300010],b[300010];
int n,m,x;

void fft(E *x,int n,int tp)
{
    if (n==1) return;
    E l[n>>1],r[n>>1];
    for (int i=0;i<n;i+=2)
        l[i>>1]=x[i],r[i>>1]=x[i+1];
    fft(l,n>>1,tp),fft(r,n>>1,tp);
    E w(1,0),wn(cos(pi*2/n),sin(pi*2/n*tp)),t;
    for (int i=0;i<n>>1;i++,w*=wn)
        t=r[i]*w,x[i]=l[i]+t,x[i+(n>>1)]=l[i]-t;
}

int main()
{
    read(n);read(m);
    int x;
    for (int i=0;i<=n;i++)
        read(x),a[i]=x;
    for (int i=0;i<=m;i++)
        read(x),b[i]=x;
    m+=n;
    for (n=1;n<=m;n<<=1);
    fft(a,n,1);fft(b,n,1);
    for (int i=0;i<=n;i++)
        a[i]*=b[i];
    fft(a,n,-1);
    for (int i=0;i<=m-1;i++)
        print((int)(a[i].real()/n+0.5)),putchar(' ');
    print((int)(a[m].real()/n+0.5)),putchar('\n');
    return 0;
}