题目描述
这是一道模板题。
给你两个多项式,请输出乘起来后的多项式。
输入格式
第一行两个整数 $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;
}