zoukankan      html  css  js  c++  java
  • 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));  //四舍五入 
    }
  • 相关阅读:
    输出 n 层的三角形,倒三角和叠在一起的沙漏
    求构成给定自然数的平方数的最小个数
    求一正整数约数的个数
    第一个符合要求的元素
    树枝节点之和是否等于给定值
    安装gcc
    杭电1004 ac code
    rabbitmq 笔记
    国行 lg g3 D858 刷 lg g3 D858hk 教程(备忘)
    MySQL存储过程错误No data
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673401.html
Copyright © 2011-2022 走看看