题链:

http://uoj.ac/problem/34

题解:

FFT入门题。

(终于接触到迷一样的FFT了)

初学者在对复数和单位根有简单了解的基础上,可以直接看《再探快速傅里叶变换》(毛啸)

(主要用于求两个序列的卷积)

代码:

递归版:

#include<bits/stdc++.h>
#define MAXN 300000
using namespace std;
const double Pi=acos(-1);
struct Z{
double real,image;
Z(double _real=0,double _image=0):real(_real),image(_image){}
Z operator - ()const {return Z(-real,-image);}
friend Z operator + (const Z &A,const Z &B){return Z(A.real+B.real,A.image+B.image);};
friend Z operator - (const Z &A,const Z &B){return A+(-B);}
friend Z operator * (const Z &A,const Z &B){return Z(A.real*B.real-A.image*B.image,A.image*B.real+A.real*B.image);}
};
void FFT(int n,Z *Y,int sn){
if(n==1) return;
Z L[n>>1],R[n>>1];
for(int k=0;k<n;k+=2)
L[k>>1]=Y[k],R[k>>1]=Y[k+1];
FFT(n/2,L,sn); FFT(n/2,R,sn);
Z dw=Z(cos(2*Pi/n),sin(sn*2*Pi/n)),w=Z(1,0),tmp;
for(int k=0;k<n/2;k++,w=w*dw)
tmp=w*R[k],Y[k]=L[k]+tmp,Y[k+n/2]=L[k]-tmp;
}
int main(){
static Z A[MAXN],B[MAXN];
int n,m; scanf("%d%d",&n,&m); n++; m++;
for(int i=0,x;i<n;i++) scanf("%d",&x),A[i]=Z(x,0);
for(int i=0,x;i<m;i++) scanf("%d",&x),B[i]=Z(x,0);
m=n+m-1; for(n=1;n<m;n<<=1);
FFT(n,A,1); FFT(n,B,1);
for(int i=0;i<n;i++) A[i]=A[i]*B[i];
FFT(n,A,-1);
for(int i=0;i<m;i++) printf("%d ",(int)(A[i].real/n+0.5));
return 0;
}

  

非递归版:

#include<bits/stdc++.h>
#define MAXN 300000
using namespace std;
const double Pi=acos(-1);
struct Z{
double real,image;
Z(double _real=0,double _image=0):real(_real),image(_image){}
Z operator - ()const {return Z(-real,-image);}
friend Z operator + (const Z &A,const Z &B){return Z(A.real+B.real,A.image+B.image);};
friend Z operator - (const Z &A,const Z &B){return A+(-B);}
friend Z operator * (const Z &A,const Z &B){return Z(A.real*B.real-A.image*B.image,A.image*B.real+A.real*B.image);}
};
int order[MAXN];
void FFT(int n,Z *Y,int sn){
for(int i=0;i<n;i++) if(i<order[i]) swap(Y[i],Y[order[i]]);
for(int d=2;d<=n;d<<=1){
Z dw=Z(cos(2*Pi/d),sin(sn*2*Pi/d)),w,tmp;
for(int i=0;w=Z(1,0),i<n;i+=d)
for(int k=i;k<i+d/2;k++,w=w*dw)
tmp=w*Y[k+d/2],Y[k+d/2]=Y[k]-tmp,Y[k]=Y[k]+tmp;
}
}
int main(){
static Z A[MAXN],B[MAXN];
int n,m,len; scanf("%d%d",&n,&m); n++; m++;
for(int i=0,x;i<n;i++) scanf("%d",&x),A[i]=Z(x,0);
for(int i=0,x;i<m;i++) scanf("%d",&x),B[i]=Z(x,0);
m=n+m-1; for(len=0,n=1;n<m;n<<=1) len++;
for(int i=1;i<n;i++) order[i]=(order[i>>1]>>1)|((i&1)<<(len-1));
FFT(n,A,1); FFT(n,B,1);
for(int i=0;i<n;i++) A[i]=A[i]*B[i];
FFT(n,A,-1);
for(int i=0;i<m;i++) printf("%d ",(int)(A[i].real/n+0.5));
return 0;
}

  

●UOJ 34 多项式乘法的更多相关文章

  1. [UOJ#34]多项式乘法

    [UOJ#34]多项式乘法 试题描述 这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入 第一行两个整数 n 和 m,分别表示两个多项式的次数. 第二行 n+1 个整数,分别表示第一个多 ...

  2. UOJ#34. 多项式乘法(NTT)

    这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入格式 第一行两个整数 nn 和 mm,分别表示两个多项式的次数. 第二行 n+1n+1 个整数,表示第一个多项式的 00 到 nn 次项 ...

  3. 【刷题】UOJ #34 多项式乘法

    这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入格式 第一行两个整数 \(n\) 和 \(m\) ,分别表示两个多项式的次数. 第二行 \(n+1\) 个整数,表示第一个多项式的 \( ...

  4. UOJ 34 多项式乘法 FFT 模板

    这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入格式 第一行两个整数 nn 和 mm,分别表示两个多项式的次数. 第二行 n+1n+1 个整数,表示第一个多项式的 00 到 nn 次项 ...

  5. 2018.11.14 uoj#34. 多项式乘法(ntt)

    传送门 今天学习nttnttntt. 其实递归方法和fftfftfft是完全相同的. 只不过fftfftfft的单位根用的是复数中的东西,而nttnttntt用的是数论里面有相同性质的原根. 代码: ...

  6. 2018.11.14 uoj#34. 多项式乘法(fft)

    传送门 NOIpNOIpNOIp爆炸不能阻止我搞oioioi的决心 信息技术课进行一点康复训练. fftfftfft板题. 代码: #include<bits/stdc++.h> usin ...

  7. UOJ 34 多项式乘法 ——NTT

    [题目分析] 快速数论变换的模板题目. 与fft的方法类似,只是把复数域中的具有循环性质的单位复数根换成了模意义下的原根. 然后和fft一样写就好了,没有精度误差,但是跑起来比较慢. 这破题目改了好长 ...

  8. UOJ 34: 多项式乘法(FFT模板题)

    关于FFT 这个博客的讲解超级棒 http://blog.miskcoo.com/2015/04/polynomial-multiplication-and-fast-fourier-transfor ...

  9. [UOJ 0034] 多项式乘法

    #34. 多项式乘法 统计 描述 提交 自定义测试 这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入格式 第一行两个整数 nn 和 mm,分别表示两个多项式的次数. 第二行 n+1n+ ...

随机推荐

  1. C语言的第一次作业总结

    PTA实验作业 题目一:温度转换 本题要求编写程序,计算华氏温度150°F对应的摄氏温度.计算公式:C=5×(F−32)/9,式中:C表示摄氏温度,F表示华氏温度,输出数据要求为整型. 1.实验代码: ...

  2. 20162311张之睿 Linux基础与Java开发环境实验报告

    实验一 Java开发环境的熟悉 实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用Eclipse 编辑.编译.运行.调试Java程序. 实验要求 1.没有Linux基础的同学建议先学习& ...

  3. 一些琐碎的C/C++知识点

    1. C++ 数组作为函数参数 在C/C++中,当数组作为函数的参数进行传递时,数组就自动退化为同类型的指针.(在32位系统中,对任意指针求sizeof结果为4) 2. C++ 中const的用法总结 ...

  4. Alpha冲刺No.3

    冲刺Day3 一.站立式会议 终于我们遇到了我们最艰难的时候,组员也反映每天做的事情越来越少,出现了问题越来越多. 人太少,时间太少,我们没有办法一个人花足够多的时间去钻研统一个问题,或许是所以组员的 ...

  5. choose the max from numbers, use scanf and if else (v1:21.9.2017,v2:23.9.2017)

    #include<stdio.h> int main(){ int a,b,c,max; printf("请输入一个数值: "); scanf("%d&quo ...

  6. Python多线程案例

    from time import ctime,sleep import threading def music(): for i in range(2): print ("I was lis ...

  7. MobileNet_v2

    研究动机: 神经网络彻底改变了机器智能的许多领域,实现了超人的准确性.然而,提高准确性的驱动力往往需要付出代价:现代先进网络需要高度计算资源,超出许多移动和嵌入式应用的能力. 主要贡献: 发明了一个新 ...

  8. Java中Math类的常用方法

    public class MathDemo { public static void main(String args[]){ /** * abs求绝对值 */ System.out.println( ...

  9. python 内置函数之lambda-filter-reduce-apply-map

    (1)lambda lambda是Python中一个很有用的语法,它允许你快速定义单行最小函数.类似于C语言中的宏,可以用在任何需要函数的地方. 基本语法如下: 函数名 = lambda args1, ...

  10. zuul入门(5)zuul 处理异常

    Object accessToken = request.getParameter("accessToken"); if(accessToken==null) { // 设置zuu ...