推荐博客 :https://oi.men.ci/fft-notes/

卷积的理解 : https://www.zhihu.com/question/22298352?rf=21686447

题目链接 :http://uoj.ac/problem/34

这是一道模板题。

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

第一行两个整数 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≤105,保证输入中的系数大于等于 0 且小于等于 9。

时间限制:1s1s

空间限制:256MB

题意  :  给你两个多项式的系数,从 0 到 n 给出,求这两个多项式相乘后的系数,从小到大输出

思路分析 : 裸的 FFT ,参考kuangbin 的板子

    就是要注意以下数组的大小,main中的 len 是 2^k , 因此当m+n = 2e5 左右时,此时 2^k = 260000+ , 因此要注意数组的大小

代码示例:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 2e5+63000;
const double pi = acos(-1.0);
int n, m;
struct Complex{
double x, y;
Complex (double _x=0, double _y=0):x(_x), y(_y){}
Complex operator -(const Complex &b)const{
return Complex(x-b.x, y-b.y);
}
Complex operator +(const Complex &b)const{
return Complex(x+b.x, y+b.y);
}
Complex operator *(const Complex &b)const{
return Complex(x*b.x-y*b.y, x*b.y+y*b.x);
}
}; Complex x1[maxn], x2[maxn];
int sum[maxn];
void change(Complex y[], int len){
for(int i = 1, j = len/2; i < len-1; i++){
if (i < j) swap(y[i], y[j]);
int k = len/2;
while(j >= k){
j -= k;
k /= 2;
}
if (j < k) j += k;
}
} void fft(Complex y[], int len, int on){
change(y, len);
for(int h = 2; h <= len; h <<= 1){
Complex wn(cos(-on*2*pi/h), sin(-on*2*pi/h));
for(int j = 0; j < len; j += h){
Complex w(1, 0);
for(int k = j; k < j+h/2; k++){
Complex u = y[k];
Complex t = w*y[k+h/2];
y[k] = u+t;
y[k+h/2] = u-t;
w = w*wn;
}
}
}
if (on == -1){
for(int i = 0; i < len; i++)
y[i].x /= len;
}
} int main () {
cin >> n >> m;
int len = 1;
while(len <= (n+m)) len <<= 1;
for(int i = 0; i <= n; i++) scanf("%lf", &x1[i].x);
fft(x1, len, 1);
for(int i = 0; i <= m; i++) scanf("%lf", &x2[i].x);
fft(x2, len, 1);
for(int i = 0; i < len; i++)
x1[i] = x1[i]*x2[i];
fft(x1, len, -1);
for(int i = 0; i <= n+m; i++){
sum[i] = (int)(x1[i].x+0.5); // sum[] 是最后的答案
printf("%d%c", sum[i], i ==n+m?'\n':' ');
}
return 0;
}

____________________________________________________________________________

int rev[maxl];
void get_rev(int bit)//bit表示二进制位数,计算一个数在二进制翻转之后形成的新数
{
for(int i=0;i<(1<<bit);i++)
rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
}
void fft(cd *a,int n,int dft)//n表示我的多项式位数
{
for(int i=0;i<n;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);
//中间的那个if保证了每个数做多只被交换了1次
//如果不写那么会有一些数被交换两次,导致最终的位置没有变
for(int step=1;step<n;step<<=1)//模拟一个合并的过程
{
cd wn=exp(cd(0,dft*PI/step));//计算当前单位复根
for(int j=0;j<n;j+=step<<1)
{
cd wnk(1,0);//计算当前单位复根
for(int k=j;k<j+step;k++)
{//蝴蝶操作
cd x=a[k];
cd y=wnk*a[k+step];
a[k]=x+y;//这就是上文中F(x)=G(x)+ωH(x)的体现
a[k+step]=x-y;
//后半个“step”中的ω一定和“前半个”中的成相反数
//“红圈”上的点转一整圈“转回来”,转半圈正好转成相反数
//一个数相反数的平方与这个数自身的平方相等..
wnk*=wn;
}
}
}
if(dft==-1) for(int i=0;i<n;i++) a[i]/=n;
//考虑到如果是IDFT操作,整个矩阵中的内容还要乘上1/n
}

FFT 入门的更多相关文章

  1. TOT 傅立叶变换 FFT 入门

    HDU 1402,计算很大的两个数相乘. FFT 只要78ms,这里: 一些FFT 入门资料:http://wenku.baidu.com/view/8bfb0bd476a20029bd642d85. ...

  2. 洛谷p3803 FFT入门

    洛谷p3803 FFT入门 ps:花了我一天的时间弄懂fft的原理,感觉fft的折半很神奇! 大致谈一谈FFT的基本原理: 对于两个多项式的卷积,可以O(n^2)求出来(妥妥的暴力) 显然一个多项式可 ...

  3. FFT入门

    这篇文章会讲讲FFT的原理和代码. 先贴picks博客(又名FFT从入门到精通):http://picks.logdown.com/posts/177631-fast-fourier-transfor ...

  4. hdu1402 FFT入门

    参考这里:http://www.cnblogs.com/pdev/p/4354705.html  http://www.cnblogs.com/pdev/p/4354629.html 题意:求大数乘法 ...

  5. bzoj2179: FFT快速傅立叶

    #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> ...

  6. 多项式FFT相关模板

    自己码了一个模板...有点辛苦...常数十分大,小心使用 #include <iostream> #include <stdio.h> #include <math.h& ...

  7. 3-idiots hdu4609 母函数+FFT 组合数学题

    http://acm.hdu.edu.cn/showproblem.php?pid=4609 题意:1e5个数,求取三个数能形成三角形的概率. 题解(这怎么会是fft入门题QAQ): 概率的算法就是三 ...

  8. 模板:快速傅里叶变换(FFT)

    参考:http://blog.csdn.net/f_zyj/article/details/76037583 如果公式炸了请去我的csdn博客:http://blog.csdn.net/luyouqi ...

  9. HDU 1402 大数乘法 FFT、NTT

    A * B Problem Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

随机推荐

  1. Nuget 通过 dotnet 命令行发布

    在开发完成一个好用的轮子就想将这个轮子发布到 nuget 让其他小伙伴可以来使用,但是 nuget.org 的登陆速度太慢,本文介绍一个命令行发布的方法,通过命令行发布的方法可以配合 Jenkins ...

  2. 【codeforces 761D】Dasha and Very Difficult Problem

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  3. 【t085】Sramoc问题

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] Sramoc(K,M)表示用数字0,1,2,...,K-1组成的自然数中能被M整除的最小数.给定K,M ...

  4. 如何用for..of.. 遍历一个普通的对象?

    如何用for..of.. 遍历一个普通的对象? 首先了解一下for..of..: 它是es6新增的一个遍历方法,但只限于迭代器(iterator), 所以普通的对象用for..of遍历 是会报错的.下 ...

  5. Django入门10--admin增强

  6. linux scull 代码read 方法

    read 的返回值由调用的应用程序解释: 如果这个值等于传递给 read 系统调用的 count 参数, 请求的字节数已经被传送. 这是最好的情况. 如果是正数, 但是小于 count, 只有部分数据 ...

  7. js中的克隆

    1.如果克隆对象是基本类型,直接复制就可以 <script type="text/javascript"> var str1 = 'abc' var str2 = st ...

  8. Linux内核 结构 struct urb

    struct urb 结构中和 USB 设备驱动有关的成员是: struct usb_device *dev 指向这个 urb 要发送到的 struct usb_device 的指针. 这个变量必须被 ...

  9. dotnet 将文件删除到回收站

    默认删除文件的时候 File.Delete 是将文件永久删除,如果是一些文档,建议删除到回收站,这样用户可以自己还原 通过 SHFileOperation 可以将文件放在回收站 本文提供的方法暂时只能 ...

  10. logisim自动生成电路

    之前再做有关logisim有关的实验时,一直在傻乎乎地连线,而我是看了mooc有关的视频时,才知道logisim有自动连线的功能. 自动连线需要事先知道输入与输出的真值表或者全部的表达式,将其填入lo ...