uoj34多项式乘法

这是一道模板题。
给你两个多项式,请输出乘起来后的多项式。

输入格式
第一行两个整数 nn 和 mm,分别表示两个多项式的次数。
第二行 n+1n+1 个整数,分别表示第一个多项式的 00 到 nn 次项前的系数。
第三行 m+1m+1 个整数,分别表示第一个多项式的 00 到 mm 次项前的系数。

输出格式
一行 n+m+1n+m+1 个整数,分别表示乘起来后的多项式的 00 到 n+mn+m 次项前的系数。

样例一
input
1 2
1 2
1 2 1

output
1 4 5 2

explanation
(1+2x)⋅(1+2x+x2)=1+4x+5x2+2x3(1+2x)⋅(1+2x+x2)=1+4x+5x2+2x3

限制与约定
0≤n,m≤1050≤n,m≤105,保证输入中的系数大于等于 00 且小于等于 99。

时间限制:1s
空间限制:256MB

分析:
如题所言,确实是一道FFT模板题,
寻求曲神帮助
虽然曲神神的有点不可思议,但人还是很亲切的
第一次写,代码极为丑陋
这里写图片描述

这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>

using namespace std;

const int N=301000;  //数组大小避免开成2的次方 
const double pi=acos(-1.0);
struct node{
    double a,b;
    node (double aa=0,double bb=0)
    {
        a=aa;b=bb;
    }
};
node a[N],b[N],omega[N],a_omega[N]; 
int n,m,k,l;

node operator +(const node &x,const node &y){return node(x.a+y.a,x.b+y.b);}
node operator -(const node &x,const node &y){return node(x.a-y.a,x.b-y.b);}
node operator *(const node &x,const node &y){return node(x.a*y.a-x.b*y.b,x.a*y.b+x.b*y.a);}
node operator *(const node &x,const double &y){return node(x.a*y,x.b*y);}

void init(int n)
{
    for (int i=0;i<n;i++)
    {
        omega[i]=node(cos(2.0*pi*i/n),sin(2.0*pi*i/n));
        a_omega[i]=node(cos(2.0*pi*i/n),-sin(2.0*pi*i/n));
    }
}

void FFT(int n,node *a,node *w)
{
    int i,j=0,k;
    for (i=0;i<n;i++)  //很显然这就是优美的rev操作 
    {
        if (i>j) swap(a[i],a[j]);
        for (int l=n>>1;(j^=l)<l;l>>=1);
    }
    for (int i=2;i<=n;i<<=1)  //合并 
    {
        int m=i>>1;  //一半区间的长度 
        for (int j=0;j<n;j+=i)
            for (k=0;k<m;k++)
            {
                node z=a[j+m+k]*w[n/i*k];
                a[j+m+k]=a[j+k]-z;
                a[j+k]=a[j+k]+z;
            } 
    }
}

int main()
{
    int fn;
    scanf("%d%d",&n,&m);
    for (int i=0;i<=n;i++) scanf("%lf",&a[i].a);
    for (int i=0;i<=m;i++) scanf("%lf",&b[i].a);
    fn=1;
    while (fn<=n+m) fn<<=1;   //找到大于n+m的最小2次幂
    init(fn); 
    FFT(fn,a,omega);
    FFT(fn,b,omega);
    for (int i=0;i<=fn;i++)
        a[i]=a[i]*b[i];
    FFT(fn,a,a_omega);
    for (int i=0;i<=n+m;i++) printf("%d ",(int)(a[i].a/fn+0.5));  //四舍五入 
}
原文地址:https://www.cnblogs.com/wutongtong3117/p/7673401.html