分治FFT学习笔记
用途
在\(O(n\log^2 n)\)的时间内做诸如
\[
f_n=\sum_{i=0}^{n-1} f_ig_{n-i}
\]
或是
\[
f_n=\sum_{i=0}^{n-1} f_if_{n-i}
\]
或是
\[
f_{k,n}=\sum_s\sum_t \sum_i f_{s,i}f_{t,n-i}
\]
等“我 卷 我 自 己”的式子。
(如果你觉得这东西多项式求逆也可以做,那么请你认真看一下第三个式子)
思想
式子一
用CDQ分治的思想:先递归做出左边,考虑左边对右边的贡献,然后递归右边。
这其实就是最简单的分治FFT,用多项式求逆也可以实现。
式子二
现在\(g\)也被\(f\)替换了,考虑仍然用上面的做法,但你会发现:你挂了。
为什么会挂呢?
上面的统计贡献的过程是这样的:分治\([l,r]\)时,先做出\([l,mid]\)的\(f\),然后把\([l,mid]\)的\(f\)和\([1,r-l+1]\)的\(g\)卷在一起,把贡献算到\([mid+1,r]\)上面去。
但是现在发现一个漏洞:如果\(g\)替换成了\(f\),那么\([1,r-l+1]\)的\(f\)可能还没有被完全算出来。
什么时候会发生这种情况呢?考虑分治结构其实和线段树结构相同,满足左边的大小\(\ge\)右边的大小,所以只有在最左边的那个区间可能会发生这种事,也就是\(l=1\)时。
那怎么办?怎么提前算出右边?
我也不知道
既然不能提前算出来,那就不算,只算出\(f\)在\([l,mid]\)的值对右边的贡献之后直接往右边递归。
显然,一个点不能对自己产生贡献,所以递归到一个点的时候肯定是对的。
而两个点时可以算出\(l\)对\(r\)的贡献,也是对的。
以此类推,它就是对的。
(完全严谨的证明我也不会啊qwq)
注意:当\(l\ne 1\)时把\([l,mid]\)和\([1,r-l+1]\)卷起来时相当于钦定一个指针在\([l,mid]\),而另一个在\([1,r-l+1]\),但实际上他们有可能会交换位置,所以要乘2。
式子三
这个式子真是丑呢……
然而直接用式子二的方法就可以了,方法并没有太大不同,除了……
注意:当\([l\ne 1]\)时¥%……&@&¥%¥,也相当于钦定了指针的位置,所以还要交换来一遍。
这么说可能比较难理解,考虑这么一个式子:
\[
f1_n=\sum_i f1_if2_{n-i}\\
f2_n=\sum_i f2_if1_{n-i}
\]
这时你不能简单地把\(f1[l,mid]\)和\(f2[1,r-l+1]\)卷起来,还要把\(f2[l,mid]\)和\(f1[1,r-l+1]\)卷起来,这才能做到不重不漏。
代码
代码现在不在我电脑上,我又那么懒,所以——
咕咕咕……
转载于:https://www.cnblogs.com/p-b-p-b/p/10931517.html
- FFT——学习笔记
- FFT算法学习笔记
- FFT学习笔记
- FFT学习笔记
- ITK学习笔记:图像FFT
- 算法学习笔记:FFT
- FFT学习笔记
- 学习笔记:CDQ分治
- 学习笔记: cdq分治
- 【cdq分治】cdq分治与整体二分学习笔记Part1.整体二分
- 【点分治】的学习笔记和众多例题
- 15. 快速傅里叶变换(FFT)原理 [学习笔记]
- 播布客教学视频_C学习笔记_8.1_统计1到100中9的个数(分治)
- 点分治学习笔记(1)
- 算法设计技巧和分析学习笔记1 (归纳法、分治和动态规划)
- msp430学习笔记-实现开方log等计算及FFT算法(待续)
- POJ1741Tree [点分治]【学习笔记】
- MIT算法导论学习笔记-Lecture3:分治法
- 【学习笔记】递归和分治策略
- FFT(快速傅里叶变换)算法学习笔记