快速傅里叶(FFT)题表

来源:互联网 发布:jeecg商业版源码下载 编辑:程序博客网 时间:2024/06/16 06:18

前言

最近终于学了FFT
以前被scy逼着学过一次没有学会,这次终于好一点了
在这里大致放一下一些FFT的题目

题表

uoj34
多项式乘法,这个估计是大多数人的入门题了吧

codevs3123
大整数高精度,其实和上面那题是差不多的

bzoj3527
化一下式子,然后两个FFT就可以得出答案了

bzoj3771
这题的话,也不是很难
你只需要分别讨论选择一个,选择两个,选择三个,然后求方案的话,就先用FFT求出构成i有多少种方案,然后去掉不合法,去掉一些重复算的就可以了。。大概想一想就能想出来了

bzoj2194
这题很明显,每个值就是
b[j]a[k+j]的总和
发现不是很好做
我们发现,如果将a数组反过来,式子就会变成
b[j]a[n(k+j)]
这个样的话两个坐标里面的和就是nk
其实这个就是很明显就是卷积的形式了,然后就FFT乱搞一下就可以了

bzoj3513
先搞出用两条线段可以弄出的长度方案,去下重,暴力算一算就好了,当模板题练一下就好了

bzoj4259
bzoj4503
这两题其实是一样的,然后我就没有想出来了,于是就只能%题解了

首先有一个O(26nlogn)的做法
先是吧T反过来
就是按位处理,比如说字母a,那么就在S里面所有a标一个1,T所有a也标一个1,然后FFT一下,就可以求出来每一位的匹配
然后别的也一样
最后看一下某一位的值是不是T的长度就可以了
当然这样肯定是会T的

于是我们需要换一种方法 题解
这里写图片描述

bzoj3509
这题想了我差不多半个多小时,最后发现其实是一个很简单的题
这题转换成,在左边选择一个数,右边选择一个数,和为自身的两倍,问有多少种方案
这个是十分容易想到的
然后我们对于一个数,就可以将两边的数FFT一下?
于是就得到了一个O(n2logn)的做法
这个做法显然不够优秀啊
因为我们一次FFT得到有用的信息实在是太少了,很浪费
于是我们考虑一次FFT做出更多的贡献
就是我们把序列分块,一个块里面的数,两侧的FFT结果明显是可以共用的
于是乎,就只剩下块里面的影响没有处理了,这个暴力处理一下就好了啊!
然后就可以搞过去了,感觉还是蛮简单的
时间复杂度,FFT会用块的个数次,然后每个点,算出答案的代价就是块的大小
那不就很简单了嘛,你就平衡一下块的大小,然后就是一个很简单的题了!

bzoj3160
这题还是蛮简单的吧。。
如果两个为i,j相等,那么他对(i+j)/2这个地方,可行方案a++
然后每一个点对答案的贡献就是2a1
然后其实你可以吧(i+j)/2/2给删掉
那么不就是卷积的形式了吗?
至于后面怎么搞,五花八门啦
然后最后连续的就用manacher扫一下就出来了

bzoj4332
感觉我最近效率很低啊,每天来到竞赛室都很困,然后就想睡觉了
这题的裸DP还是蛮好弄的吧。。
就是f[i][j]表示一下就可以了
然后这个的复杂度很明显是O(m2)
然后我们考虑进行倍增,如果我们没有”所有没有糖的人都要在最后连续的一段”,这个限制,那么我们就直接用FFT倍增转移就可以了
现在多了一个限制,就不好这么做了
但是没有关系,我们可以搞多一个数组g
表示在当前的小朋友个数里面,分了i个糖果,并且一定要有一段后缀0的答案和
然后f数组表示,我们不可以有后缀0的答案和
至于转移,f的就很好弄啦
然后g的话,就是前面一半是f的,后面一半是g的并起来
也就是g[i]=g[ik]f[k]
当然f是覆盖的,g是累加的(这个很重要,我开始想成g是覆盖的,就一直没有弄出来)
因为前面一半的小朋友没有糖的情况是前面处理的嘛
然后就做完了

bzoj4827
就用一个水题来暂时吧这个专题告一段落吧。。
这题的话,你就把a串倍长,b串反串
然后随便化下式子,就可以做出来了
然后考虑到m很小,于是你就暴力地枚举要加多少
注意的是,这里加其实等于另外一个串减
所以你只需要做一次就可以了,就是枚举某个串加多少,范围是mn
时间复杂度O(nlogn)

原创粉丝点击