BZOJ 2194 快速傅里叶之二 题解
题目描述
求:。
推导
一般卷积是和一定,然而这个是差一定,于是我们考虑把 反过来(其实反 也可以)。
则 。
令 。
则 。
的推导很像卷积,考虑将其变换形式,即 。
至此,可以通过 FFT 来求解。
/* * Title: #2194. 快速傅立叶之二 * Source: HydroOJ-BZOJ * URL: https://hydro.ac/d/bzoj/p/2194 * Author: Steven_lzx * Command: -std=c++23 -Wall -fno-ms-extensions */ #include <bits/stdc++.h> using namespace std; typedef complex<double> cd; const int MAXN=1<<20; const double PI=acos(-1),TAU=2*PI; cd a[MAXN],b[MAXN]; void FFT(cd *a,int n,int dft) { cd w,wk,x,y; for(int i=0,k=0;i<n;i++) { if(i>k) swap(a[i],a[k]); for(int j=n>>1;(k^=j)<j;j>>=1); } for(int k=2;k<=n;k<<=1) { w=cd(cos(TAU*dft/k),sin(TAU*dft/k)); for(int i=0;i<n;i+=k) { wk=cd(1,0); for(int j=0;j<(k>>1);j++) { x=a[i+j]; y=wk*a[i+j+(k>>1)]; a[i+j]=x+y; a[i+j+(k>>1)]=x-y; wk*=w; } } } return; } int main() { int n,len; double x,y; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%lf%lf",&x,&y); a[i]=cd(x,0); b[n-i-1]=cd(y,0); } for(len=1;len<=(n<<1);len<<=1); FFT(a,len,1); FFT(b,len,1); for(int i=0;i<len;i++) { a[i]*=b[i]; } FFT(a,len,-1); for(int i=n-1;i<(n<<1)-1;i++) printf("%lld\n",(long long)(a[i].real()/len+0.1)); return 0; }
本文作者:Day_Dreamer_D
本文链接:https://www.cnblogs.com/2020gyk080/p/16829752.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
标签:
,
,
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步