FFT

news/2024/11/16 15:52:40/文章来源:https://www.cnblogs.com/kbzcz/p/18077264/FFT

这东西对初中生挺友好的。


前置知识

  1. 复数
    形如 \(a+bi(a,b\in \mathbb{R})\) 的数叫复数,其中 \(i^2=-1\)
    复数乘法:\((a+bi)(c+di)=ac-bd+(ad+bc)i\)。乘法分配律即可。

  2. 复平面
    \(a\)\(x\) 轴,\(b\)\(y\)轴所组成的平面叫复平面。每个复数都对应复平面上一点。

  3. 单位根
    以原点为圆心,\(1\) 为半径所形成的圆叫单位圆。以 \((1,0)\) 为起点,用 \(n\) 个点圆上的点将单位圆分成 \(n\) 等分。容易发现,这 \(n\) 个点正好是 \(w^n=1\)\(n\) 个解。


如图为一个单位圆和一些单位根。

按角度大小记这 \(n\) 个点为 \(w_n^0,w_n^1\dots w_n^{n-1}\),当 \(n\)\(2\) 的次幂时,有如下性质:

  1. \(w_n^k=-w_n^{k+\frac{n}{2}}\),也就是说他们两两互为相反数。
  2. \(w_n^k=w_n^{n+k}\),说明单位根有周期性。
  3. \(n\) 个单位根平方后,他们依然是两两互为相反数。

这些性质决定了我们为什么选它来求值。


FFT

其实就是将两个多项式转化成点值表示相乘在转回来的过程。

\(F(x)=\sum\limits_{i=0}^m a_ix^i\)\(m\)是两个多项式相乘后的次数。默认 \(n\) 为最小的大于 \(m\)\(2\) 的次幂(方便计算)。将 \(F\) 按次数奇偶分成两个函数。

\[f_0(x^2)=\sum\limits_{i=0}^{n/2-1}a_{2i}x^{i} \]

\[f_1(x^2)=\sum\limits_{i=0}^{n/2-1}a_{2i+1}x^{i} \]

\[F(x)=f_0(x^2)+xf_1(x^2) \]

显然 \(f_0,f_1\) 都是偶函数,也就是说 \(x\) 的值与 \(-x\) 是相等的。因此,我们还可以表示出

\[F(-x)=f_0(x^2)-xf_1(x^2) \]

所以要取的点和多项式的次数都变为了原来的一半,可以用递归处理。但对于 \(f_0,f_1\) 而言所有的点值都是正的,不存在相反数,无法递归。所以我们尝试寻找一些更特殊的数,单位根正好满足这个性质,因为所有单位根平方后依然是两两互为相反数的。

举个例子:

这是当 \(n=4\) 时递归的 \(x\) 值。

这是当 \(n=8\) 时的 \(x\) 值。

当递归到只剩一个常数项时,递归结束。

我们可以用相同的方式将另一个多项式的点值求出来。


当我们求出两个多项式点值并相乘后,如何将点值重新转化为系数呢?

我个人认为这很人类智慧。

设相乘后的多项式为 \(G(x)=\sum\limits_{i=0}^{n-1} b_ix^i\),将 \(w_n^0,w_n^{-1},\dots w_n^{1-n}\) 带入得到的多项式中进行 \(\text{FFT}\),再将所得的多项式的每一项除以 \(n\) 就是每一项对应的系数。

证明 :

\(c_k=\sum\limits_{i=0}^{n-1}b_i(w_n^{-k})^i\),将 \(b_i\) 用多项式表示 \(b_i=\sum\limits_{j=0}^{n-1}a_j(w_n^i)^j\),带入上式中

\[\begin{aligned} c_k&=\sum\limits_{i=0}^{n-1}(\sum\limits_{j=0}^{n-1}a_j(w_n^i)^j)(w_n^{-k})^i\\ &=\sum\limits_{i=0}^{n-1}\sum\limits_{j=0}^{n-1} a_j(w_n^i)^j(w_n^{-k})^i\\ &=\sum\limits_{i=0}^{n-1}\sum\limits_{j=0}^{n-1}a_j(w_n^{j-k})^i\\ &=\sum\limits_{j=0}^{n-1}a_j\sum\limits_{i=0}^{n-1}(w_n^{j-k})^i \end{aligned}\]

\(j=k\) 时, \(c_k=na_j\)
\(j \ne k\)

\[\begin{aligned} \sum\limits_{i=0}^{n-1}(w_n^{j-k})^i&=\frac{(w_n^{j-k})^n-1}{w_n^{j-k}-1}\\&=\frac{(w_n^n)^{j-k}-1}{w_n^{j-k}-1}\\ &=0\end{aligned} \]

所以,\(c_k=na_j\)\(\frac{c_k}{n}\) 就是我们要求的系数。


至此,\(\text{FFT}\) 的所有流程都已完成。

模板题

代码(递归)

bool _Start;
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define Tp template<typename T>
#define Ts template<typename T,typename... _T>
Tp il void read(T& x) {x=0;bool f=0;char c=getchar();for(;!isdigit(c);c=getchar()) f|=c=='-';for(;isdigit(c);c=getchar()) x=(x<<1)+(x<<3)+(c^48);x=(f?-x:x);
}Ts il void read(T& x,_T&... y) {read(x),read(y...);}
using comp=complex<double>;
const double pi=acos(-1);
const int N=1<<21;
int n,m;
comp A[N],B[N];
void FFT(comp F[],int n,int tp) {if(n==1) return ;comp F0[(n>>1)+5],F1[(n>>1)+5];for(int i=0;i<n;i+=2)F0[i>>1]=F[i],F1[i>>1]=F[i+1];FFT(F0,n>>1,tp),FFT(F1,n>>1,tp);comp wn=exp(comp(0,2*pi*tp/n)),w=1;for(int i=0;i<(n>>1);i++,w*=wn) {F[i]=F0[i]+w*F1[i];F[i+(n>>1)]=F0[i]-w*F1[i];}
}
void mul(comp f[],comp g[]) {int lim=1;while(lim<=n+m) lim<<=1;FFT(f,lim,1),FFT(g,lim,1);for(int i=0;i<lim;i++) f[i]*=g[i];FFT(f,lim,-1);for(int i=0;i<lim;i++) f[i]/=lim;
}
bool _End;
int main() {fprintf(stderr,"Memory: %.4lf Mib\n",abs(&_End-&_Start)/1048576.0);read(n,m);for(int i=0,x;i<=n;i++) read(x),A[i]=x;for(int i=0,x;i<=m;i++) read(x),B[i]=x;mul(A,B);for(int i=0;i<=n+m;i++) printf("%d ",(int)(A[i].real()+0.5));return 0;
}

优化

balabalabala.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/742245.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

R语言将多景遥感影像拼接在一起的方法

本文介绍基于R语言中的raster包,遍历文件夹,读取文件夹下的大量栅格遥感影像,并逐一对每一景栅格图像加以拼接、融合,使得全部栅格遥感影像拼接为完整的一景图像的方法~本文介绍基于R语言中的raster包,遍历文件夹,读取文件夹下的大量栅格遥感影像,并逐一对每一景栅格图像…

使用pyqt5制作简单计分桌面应用

这是一个自己写的使用pyqt5制作简单计分桌面应用的实例,包含完整代码,希望对大家有所帮助。制作这个小程序的起因是因为有个艺术类比赛需要设计这个一个桌面程序,方便统分。这是一个自己写的使用pyqt5制作简单计分桌面应用的实例,希望对大家有所帮助。制作这个小程序的起因…

Linux-Cgroup V2 初体验

本文主要记录 Linux Cgroup V2 版本基本使用操作,包括 cpu、memory 子系统演示。1. 开启 Cgroup V2 版本检查 通过下面这条命令来查看当前系统使用的 Cgroups V1 还是 V2 stat -fc %T /sys/fs/cgroup/如果输出是cgroup2fs 那就是 V2,就像这样 root@tezn:~# stat -fc %T /sys/…

Linux系统基础学习

系统目录结构 登录系统之后输入ls命令查看系统目录系统常用的目录/bin 存放着最常用的命令,包括用户和系统管理员都会使用的命令。 /boot 存放启动linux的核心文件,包括内核文件、引导文件、镜像文件 /dev 存放着 Linux 系统中所有的设备文件,如硬盘、CD-ROM等 /home 用户的…

《穷查理思维模型实战课程——一个月一场》

好久好久没更新了。穷查理思维模型实战课程——一个月一场 查理芒格的去世,让了当今没有孔子在世。但是他的智慧会让我们继续前行。

.Net Windows Forms(窗体程序)在服务端运行不了的问题

.Net Windows Forms(窗体程序)在服务端运行不了的问题(本机可以) 原因:是在Form1的构造函数中多了这几行,在服务端找不到配制文件。//DomSqlMapBuilder builder = new DomSqlMapBuilder();//ISqlMapper mapper = builder.Configure(@"..\..\App_Data\SqlMap.config…

基于业财一体化和数据集成的费用协同管理系统-虎珀

某药企,作为高新技术企业、也是中国医药工业百强。其业务集药物研发、生产、销售、商业批发和国际营销为一体,为进一步提升集团内部费用管理的精细化与标准化水平,该企业决定引入先进的信息化费用核算系统,将其作为集团费用管理体系中的重要组成部分。 此系统要能够适应不同…

ABC361

A link先输出前\(k\)个,再输出\(x\),最后输出后面的。点击查看代码 #include<bits/stdc++.h>using namespace std;int n,k,x;signed main(){cin >> n >> k >> x;for(int i = 1;i <= n;++ i){int a;cin >> a;cout << a << "…

ali - Kubernetes镜像源

1. Kubernetes镜像源配置 由于 Kubernetes 官方变更了仓库的存储路径以及使用方式,如果需要使用1.28 及以上版本,请使用 新版配置方法 进行配置。 下载地址:https://mirrors.aliyun.com/kubernetes/ 新版下载地址:https://mirrors.aliyun.com/kubernetes-new/ 1.1 配置方法…

【日记】什么时候混到连信封都要从单位顺这种地步了……(1171 字)

正文早上 5 点半,被手机的暴雨红色预警吵醒了。它居然还会发出警报声,有点意外。当时翻身看手机,只见红红的一大片,我还以为是地震,给我瞬间吓清醒了。早上连发两个暴雨红色预警,中午消停了一会儿,晚上又开始发。今晚跟何老师清假了,说休息一天,怕去了之后回不来了。刚…

Kubernetes安装-kubeadm方式

环境 1.软件版本系统版本centos 7.9(内核采用4.19)docker 20.10.15kubeadm 1.22.172.ip划分主机名ip地址系统配置kubeadm-master 10.103.236.201 2core_2gkubeadm-node01 10.103.236.202 1core_2gkubeadm-node02 10.103.236.203 1core_2gkubeadm-node03 10.103.236.204 1core_2…

Redis高可用之持久化、主从复制

一、Redis高可用策略概述持久化 持久化是最简单的高可用方法,主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失。主从复制 主从复制是高可用Redis的基础,主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复哨兵 在主从复制的基础上,…