洛谷p3803 FFT入门

ps:花了我一天的时间弄懂fft的原理,感觉fft的折半很神奇!

大致谈一谈FFT的基本原理:

 对于两个多项式的卷积,可以O(n^2)求出来(妥妥的暴力)

 显然一个多项式可以用a0+a1X+a2X2+a3X3+a4X^4……表示。

 也可以用(x1,y1),(x2,y2),(x3,y3),(x4,y4)的点集来表示。

 用点值表示有一个好处:两个多项式的卷积可以直接取相同的x值,y值相乘得到。

 那么,怎么转化为点值表示呢?

 直接代进去?显然也是O(n^2),没用……

 设\(A(X)=a0+a1X+a2X^2+a3X^3+a4X^4……\)

 \(A[0](X)=a0+a2X+a4X^2……\)

 \(A[1](X)=a1+a3X+a5X^2……\)

 那么A(X)=A0(X2)+X*A1(X2);

 然而,X^2仍会有N种不同的取值。

 引入一个复数根可以很好的解决这个问题:设i=\(\sqrt{-1}\)

 \(cosθ+i∗sinθ\)有很多很好的性质:

 例如\((cosθ+i∗sinθ)^k=coskθ+i*sinkθ\)

 记\(Wn=cos\frac{2π}{n}+i∗sin\frac{2π}{n}\)

 \(A(W{n}^{k})=A[0](((W{n}^{k})^2)+W{n}^{k}*A[1]((W{n}^{k})^2)\)

 因为$$(W{n}{k})2=W{n}{2k}=cos\frac{2π*2k}{n}+i∗sin\frac{2π*2k}{n}=cos\frac{2πk}{\frac{n}{2}}+i∗sin\frac{2πk}{\frac{n}{2}}=(W{\frac{n}{2}{k}})$$

 所以$$A(W{n}^{k})=A0+W{n}{k}*A[1]((W{n}^{k})^2)=A[0]W{\frac{n}{2}{k}}+W{n}{k}*A[1]W{\frac{n}{2}}{k}$$

 根据三角函数的周期性:2π为一个周期。

 \(W{n}^{k}=W{n}^{k mod n}\)

 那么\(A(W{n}^{k})=A[0]W{\frac{n}{2}}^{k}+W{n}^{k}*A[1]W{\frac{n}{2}^{k}}\)可以拆成两部分,设\(t<\frac{n}{2}\)

 \(A(W{n}^{t})=A[0]W{\frac{n}{2}}^{t}+W{n}^{t}*A[1]W{\frac{n}{2}^{t}}\)

 \(A(W{n}^{t+\frac{n}{2}})=A[0]W{\frac{n}{2}}^{t}-W{n}^{t}*A[1]W{\frac{n}{2}^{t}}\)

 因为\(W{n}^{t+\frac{n}{2}}=W{n}^{t}*W{n}^{\frac{n}{2}}\)

 \(W{n}^{\frac{n}{2}}=W{2}=cos\frac{2π}{2}+i*sin\frac{2π}{2}=cosπ+i*sinπ=-1\)

 证毕,啦啦啦!

 一直折半下去算就可以将时间优化到O(nlogn)

 

 上图摘自算法导论。算法导论下载,提取码qcfs

 一题洛谷的裸题p3803

【代码】

#include<cstdio>
#include<algorithm>
#include<cmath> using namespace std; typedef long long ll; const int N=1e6+10;
const double pi=acos(-1.0);
int n,m,nn,k;
struct Complex {
double real,image; //real+i*image
Complex(){}
Complex(double _real,double _image)
{
real=_real; image=_image;
}
friend Complex operator + (Complex A,Complex B) { return (Complex(A.real+B.real,A.image+B.image)); }
friend Complex operator - (Complex A,Complex B) { return (Complex(A.real-B.real,A.image-B.image)); }
friend Complex operator * (Complex A,Complex B) { return (Complex(A.real*B.real-A.image*B.image,A.real*B.image+A.image*B.real)); }
} A[N<<2],B[N<<2],C[N<<2];
int rev[N<<2]; void FFT(Complex *A,int n,int DFT)
{
for(int i=0;i<n;i++) if(i<rev[i]) swap(A[i],A[rev[i]]);
for(int s=1;(1<<s)<=n;s++)
{
int mi=(1<<s);
Complex wn=Complex(cos(2*pi/mi),sin(2*pi/mi)*DFT);
for(int t=0;t<n;t+=mi)
{
Complex w=Complex(1,0);
for(int j=0;j<(mi>>1);j++)
{
Complex u=A[t+j],v=w*A[t+j+(mi>>1)];
A[t+j]=u+v; A[t+j+(mi>>1)]=u-v;
w=w*wn;
}
}
}
if(DFT==-1) for(int i=0;i<n;i++) A[i].real/=n,A[i].image/=n;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<=n;i++) { int xx; scanf("%d",&xx); A[i]=Complex(xx,0); }
for(int i=0;i<=m;i++) { int xx; scanf("%d",&xx); B[i]=Complex(xx,0); }
m+=n; k=0;
for(nn=1;nn<=m;nn<<=1) k++;
for(int i=0;i<nn;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
FFT(A,nn,1); FFT(B,nn,1);
for(int i=0;i<=nn;i++) C[i]=A[i]*B[i];
FFT(C,nn,-1);
for(int i=0;i<=m;i++) printf("%d ",(int)(C[i].real+0.5));
printf("\n");
return 0;
}

ps:这篇总结写得真心累……

洛谷p3803 FFT入门的更多相关文章

  1. FFT/NTT总结+洛谷P3803 【模板】多项式乘法(FFT)(FFT/NTT)

    前言 众所周知,这两个东西都是用来算多项式乘法的. 对于这种常人思维难以理解的东西,就少些理解,多背板子吧! 因此只总结一下思路和代码,什么概念和推式子就靠巨佬们吧 推荐自为风月马前卒巨佬的概念和定理 ...

  2. 洛谷P3803 【模板】多项式乘法(FFT)

    P3803 [模板]多项式乘法(FFT) 题目背景 这是一道FFT模板题 题目描述 给定一个n次多项式F(x),和一个m次多项式G(x). 请求出F(x)和G(x)的卷积. 输入输出格式 输入格式: ...

  3. 洛谷 P3803 多项式乘法(FFT) —— FFT

    题目:https://www.luogu.org/problemnew/show/P3803 终于学了FFT了! 参考博客:https://www.cnblogs.com/zwfymqz/p/8244 ...

  4. 洛谷 - P3803 -【模板】多项式乘法(FFT) - NTT

    https://www.luogu.org/problemnew/show/P3803 看别人偏偏就是要用NTT去过.实验证明大概是这样用.求0~n的多项式和0~m的多项式的乘积.注意MAXN取值.A ...

  5. 洛谷 - P3803 - 【模板】多项式乘法(FFT) - FFT

    https://www.luogu.org/problemnew/show/P3803 用反向学习的FFT通过这个东西. #include <bits/stdc++.h> using na ...

  6. 洛谷 P3803 【模板】多项式乘法(FFT)

    题目链接:P3803 [模板]多项式乘法(FFT) 题意 给定一个 \(n\) 次多项式 \(F(x)\) 和一个 \(m\) 次多项式 \(G(x)\),求 \(F(x)\) 和 \(G(x)\) ...

  7. 2018.08.28 洛谷P3803 【模板】多项式乘法(FFT)

    传送门 fft模板题. 终于学会fft了. 这个方法真是神奇! 经过试验发现手写的complex快得多啊! 代码: #include<iostream> #include<cstdi ...

  8. 【总结】对FFT的理解 / 【洛谷 P3803】 【模板】多项式乘法(FFT)

    题目链接 \(\Huge\text{无图,慎入}\) \(FFT\)即快速傅里叶变换,用于加速多项式乘法. 如果暴力做卷积的话就是一个多项式的每个单项式去乘另一个多项式然后加起来,时间复杂度为\(O( ...

  9. [洛谷P3803] 【模板】多项式乘法(FFT, NTT)

    题目大意:$FFT$,给你两个多项式,请输出乘起来后的多项式. 题解:$FFT$,由于给的$n$不是很大,也可以用$NTT$做 卡点:无 C++ Code:  FFT: #include <cs ...

随机推荐

  1. RT-Thread 设备驱动SPI浅析及使用

    OS版本:RT-Thread 4.0.0 测试BSP:STM32F407 SPI简介 SPI总线框架其实和I2C差不多,可以说都是总线设备+从设备,但SPI设备的通信时序配置并不固定,也就是说控制特定 ...

  2. HBase编程 API入门系列之delete.deleteColumn和delete.deleteColumns区别(客户端而言)(4)

    心得,写在前面的话,也许,中间会要多次执行,连接超时,多试试就好了. delete.deleteColumn和delete.deleteColumns区别是: deleteColumn是删除某一个列簇 ...

  3. lua单链表实现

    List = {} --创建一个节点 function List.new(val) return {pnext = nil, value = val} end --往一个节点后添加一个节点 funct ...

  4. html中<frameset>标签,框架结构各窗口的父级菜单子级菜单关系

    这个问题搞得我头大,并且在查过百度后各位大佬给出的解释我都不能理解,应该是我太白的原因,希望我写的能好理解. 下面文章窗口1.2.3,在代码里分别为chuangkou.chuangkou1.chuan ...

  5. CorelDRAW X8超低价优惠啦,你却还在用CDR X4破解?!

    最近大火的<都挺好> 已经完美收官 出于好奇,小编也正在追剧呢 同样出生在畸形的原生家庭 长大后 有钱就是苏明玉 没钱就是樊胜美 所以不要抱怨老天给了你怎样的资源 想要什么就要靠自己的双手 ...

  6. Here comes Treble: A modular base for Android

    On the Android team, we view each dessert release as an opportunity to make Android better for our u ...

  7. BZOJ 1305: [CQOI2009]dance跳舞 网络最大流_二分答案_建模

    Description 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲.有一些男孩女孩相互喜欢,而其他相互不喜欢(不会 ...

  8. bzoj 1296: [SCOI2009]粉刷匠 动态规划

    Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个 ...

  9. Linux下清空文件的几种方法

    $ : > filename $ > filename $ echo "" > filename $ echo > filename $ cat /dev/ ...

  10. Quoit Design (HDU 1007)平面的最近点对

    题目大意:给定平面上的 n 个点,求距离最近的两个点的距离的一半. n <= 10^5.   晕乎乎的度过了一上午... 总之来学习下分治吧233 分治就是把大问题拆成小问题,然后根据对小问题处 ...