LG3803 「模板」快速傅里叶变换 FFT

问题描述

LG3803


题解

点我


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std;

const int maxn=1350000;
const double Pi=acos(-1);
int n,m;

struct CP{
    CP(double X=0,double Y=0) {x=X,y=Y;}
    double x,y;
    CP operator + (CP const &a) const
    {return CP(x+a.x,y+a.y);}
    CP operator - (CP const &a) const
    {return CP(x-a.x,y-a.y);}
    CP operator * (CP const &a) const
    {return CP(x*a.x-y*a.y,x*a.y+y*a.x);}
}f[maxn<<1],p[maxn<<1];

int tr[maxn<<1];

void fft(CP *f,bool type){
    for(int i=0;i<n;i++) if(i<tr[i]) swap(f[i],f[tr[i]]);
    for(int p=2;p<=n;p<<=1){
        int len=p>>1;
        CP tG(cos(2*Pi/p),sin(2*Pi/p));
        if(!type) tG.y*=-1;
        for(int k=0;k<n;k+=p){
            CP buf(1,0);
            for(int l=k;l<k+len;l++){
                CP tt=buf*f[l+len];
                f[l+len]=f[l]-tt;
                f[l]=f[l]+tt;
                buf=buf*tG;
            }
        }
    }
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<=n;i++) scanf("%lf",&f[i].x);
    for(int i=0;i<=m;i++) scanf("%lf",&p[i].x);
    for(m+=n,n=1;n<=m;n<<=1);
    for(int i=0;i<n;i++) tr[i]=(tr[i>>1]>>1)|((i&1)?n>>1:0);
    fft(f,1);fft(p,1);
    for(int i=0;i<n;i++) f[i]=f[i]*p[i];
    fft(f,0);
    for(int i=0;i<=m;i++){
        printf("%d ",(int)(f[i].x/n+0.49));
    }
}

原文地址:https://www.cnblogs.com/liubainian/p/12127811.html

时间: 2024-11-06 10:00:37

LG3803 「模板」快速傅里叶变换 FFT的相关文章

[学习笔记] 多项式与快速傅里叶变换(FFT)基础

引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积(或者多项式乘法/高精度乘法), 而代码量却非常小. 博主一年半前曾经因COGS的一道叫做"神秘的常数 $\pi$"的题目而去学习过FFT, 但是基本就是照着板子打打完并不知道自己在写些什么鬼畜的东西OwO 不过...博主这几天突然照着算法导论自己看了一遍发现自己似乎突然意识到了什么OwO然后就打了一道板子题还1A了OwO再加上午考试差点AK

快速傅里叶变换FFT

快速傅里叶变换FFT DFT是信号分析与处理中的一种重要变换.但直接计算DFT的计算量与变换区间长度N的平方成正比,当N较大时,计算量太大,直接用DFT算法进行谱分析和信号的实时处理是不切实际的. 1.直接计算DFT 长度为N的有限长序列x(n)的DFT为: 2.减少运算量的思路和方法 思路:N点DFT的复乘次数等于N2.把N点DFT分解为几个较短的DFT,可使乘法次数大大减少.另外,旋转因子WmN具有周期性和对称性. (考虑x(n)为复数序列的一般情况,对某一个k值,直接按上式计算X(k)值需

「模板」 FHQ_Treap

「模板」 FHQ_Treap <题目链接> 我也是偶然发现我还没发过FHQ_Treap的板子. 那就发一波吧. 这个速度实在不算快,但是不用旋转,并且好写. 更重要的是,Splay 可以做的事情它都可以做!比如区间操作,以及LCT相关- 而且它还可以可持久化!(虽然目前还没有学) Capella 认为,不涉及区间操作时,用快一些的平衡树(SBT/Treap/替罪羊...)较好,涉及区间操作而又不想写大量代码的话,FHQ_Treap 不失为一种极好的选择. 下一篇写 FHQ_Treap 的区间操

「模板」 割点

「模板」 割点 <题目链接> 不会点双导致的 APIO 完挂. 本应该联赛前学的东西,不及时学,就只有等到变回联赛选手后再学了吧. 以及,以后放弃链式前向星,存图一律指针邻接表. #include <algorithm> #include <cstdio> using std::min; const int MAXN=100010; bool cut[MAXN]; int n,m,DFN_num,ans,DFN[MAXN],low[MAXN]; struct Edge

「模板」 树套树

「模板」 树套树 <题目链接> 线段树套 SBT. 有生以来写过的最长代码. 虽然能过,但我删除 SBT 点的时候没回收内存!写了就 RE! 先放上来吧,回收内存调出来了再修改qwq. #include <algorithm> #include <climits> #include <cstdio> using std::max; using std::min; const int MAXN=50010; int n,m; class SegmentTree

「模板」 线段树——区间乘 &amp;&amp; 区间加 &amp;&amp; 区间求和

「模板」 线段树--区间乘 && 区间加 && 区间求和 <题目链接> 原来的代码太恶心了,重贴一遍. #include <cstdio> int n,m; long long p; class SegmentTree { private: struct Node { int l,r; long long v,mul,add; Node *c[2]; Node(int l,int r):l(l),r(r),mul(1LL),add(0LL) { c[

浅谈范德蒙德(Vandermonde)方阵的逆矩阵的求法以及快速傅里叶变换(FFT)中IDFT的原理

浅谈范德蒙德(Vandermonde)方阵的逆矩阵与拉格朗日(Lagrange)插值的关系以及快速傅里叶变换(FFT)中IDFT的原理 只要稍微看过一点线性代数的应该都知道范德蒙德行列式. \[V(x_0,x_1,\cdots ,x_{n-1})=\begin{bmatrix} {1}&{1}&{\cdots}&{1}\{x_{0}}&{x_{1}}&{\cdots}&{x_{n-1}}\{x_{0}^2}&{x_{1}^2}&{\cdots

【笔记篇】(理论向)快速傅里叶变换(FFT)学习笔记w

现在真是一碰电脑就很颓废啊... 于是早晨把电脑锁上然后在旁边啃了一节课多的算导, 把FFT的基本原理整明白了.. 但是我并不觉得自己能讲明白... Fast Fourier Transformation, 快速傅里叶变换, 是DFT(Discrete Fourier Transform, 离散傅里叶变换)的快速实现版本. 据说在信号处理领域广泛的应用, 而且在OI中也有广泛的应用(比如SDOI2017 R2至少考了两道), 所以有必要学习一波.. 划重点: 其实学习FFT最好的教材是<算法导论

【转】快速傅里叶变换(FFT)详解

目录 前言 多项式 系数表示法 点值表示法 复数 向量 圆的弧度制 平行四边形定则 复数 运算法则 单位根 单位根的性质 快速傅里叶变换 快速傅里叶逆变换 理论总结 递归实现 迭代实现 本文只讨论FFT在信息学奥赛中的应用 文中内容均为个人理解,如有错误请指出,不胜感激 回到顶部 前言 先解释几个比较容易混淆的缩写吧 DFT:离散傅里叶变换->O(n2)O(n2)计算多项式乘法 FFT:快速傅里叶变换->O(n?log(n)O(n?log?(n)计算多项式乘法 FNTT/NTT:快速傅里叶变换