前言
最近终于学了FFT
以前被scy逼着学过一次没有学会,这次终于好一点了
在这里大致放一下一些FFT的题目
题表
uoj34
多项式乘法,这个估计是大多数人的入门题了吧
codevs3123
大整数高精度,其实和上面那题是差不多的
bzoj3527
化一下式子,然后两个FFT就可以得出答案了
bzoj3771
这题的话,也不是很难
你只需要分别讨论选择一个,选择两个,选择三个,然后求方案的话,就先用FFT求出构成i有多少种方案,然后去掉不合法,去掉一些重复算的就可以了。。大概想一想就能想出来了
bzoj2194
这题很明显,每个值就是
b[j]∗a[k+j]
b
[
j
]
∗
a
[
k
+
j
]
的总和
发现不是很好做
我们发现,如果将a数组反过来,式子就会变成
b[j]∗a[n−(k+j)]
b
[
j
]
∗
a
[
n
−
(
k
+
j
)
]
这个样的话两个坐标里面的和就是
n−k
n
−
k
其实这个就是很明显就是卷积的形式了,然后就FFT乱搞一下就可以了
bzoj3513
先搞出用两条线段可以弄出的长度方案,去下重,暴力算一算就好了,当模板题练一下就好了
bzoj4259
bzoj4503
这两题其实是一样的,然后我就没有想出来了,于是就只能%题解了
首先有一个
O(26nlogn)
O
(
26
n
l
o
g
n
)
的做法
先是吧T反过来
就是按位处理,比如说字母a,那么就在S里面所有a标一个1,T所有a也标一个1,然后FFT一下,就可以求出来每一位的匹配
然后别的也一样
最后看一下某一位的值是不是T的长度就可以了
当然这样肯定是会T的
于是我们需要换一种方法 题解
bzoj3509
这题想了我差不多半个多小时,最后发现其实是一个很简单的题
这题转换成,在左边选择一个数,右边选择一个数,和为自身的两倍,问有多少种方案
这个是十分容易想到的
然后我们对于一个数,就可以将两边的数FFT一下?
于是就得到了一个
O(n2logn)
O
(
n
2
l
o
g
n
)
的做法
这个做法显然不够优秀啊
因为我们一次FFT得到有用的信息实在是太少了,很浪费
于是我们考虑一次FFT做出更多的贡献
就是我们把序列分块,一个块里面的数,两侧的FFT结果明显是可以共用的
于是乎,就只剩下块里面的影响没有处理了,这个暴力处理一下就好了啊!
然后就可以搞过去了,感觉还是蛮简单的
时间复杂度,FFT会用块的个数次,然后每个点,算出答案的代价就是块的大小
那不就很简单了嘛,你就平衡一下块的大小,然后就是一个很简单的题了!
bzoj3160
这题还是蛮简单的吧。。
如果两个为i,j相等,那么他对
(i+j)/2
(
i
+
j
)
/
2
这个地方,可行方案a++
然后每一个点对答案的贡献就是
2a−1
2
a
−
1
然后其实你可以吧
(i+j)/2
(
i
+
j
)
/
2
的
/2
/
2
给删掉
那么不就是卷积的形式了吗?
至于后面怎么搞,五花八门啦
然后最后连续的就用manacher扫一下就出来了
bzoj4332
感觉我最近效率很低啊,每天来到竞赛室都很困,然后就想睡觉了
这题的裸DP还是蛮好弄的吧。。
就是
f[i][j]
f
[
i
]
[
j
]
表示一下就可以了
然后这个的复杂度很明显是
O(m2)
O
(
m
2
)
的
然后我们考虑进行倍增,如果我们没有”所有没有糖的人都要在最后连续的一段”,这个限制,那么我们就直接用FFT倍增转移就可以了
现在多了一个限制,就不好这么做了
但是没有关系,我们可以搞多一个数组
g
g
表示在当前的小朋友个数里面,分了个糖果,并且一定要有一段后缀
0
0
的答案和
然后数组表示,我们不可以有后缀
0
0
的答案和
至于转移,f的就很好弄啦
然后的话,就是前面一半是
f
f
的,后面一半是的并起来
也就是
g[i]=g[i−k]∗f[k]
g
[
i
]
=
g
[
i
−
k
]
∗
f
[
k
]
当然f是覆盖的,g是累加的(这个很重要,我开始想成g是覆盖的,就一直没有弄出来)
因为前面一半的小朋友没有糖的情况是前面处理的嘛
然后就做完了
bzoj4827
就用一个水题来暂时吧这个专题告一段落吧。。
这题的话,你就把a串倍长,b串反串
然后随便化下式子,就可以做出来了
然后考虑到m很小,于是你就暴力地枚举要加多少
注意的是,这里加其实等于另外一个串减
所以你只需要做一次就可以了,就是枚举某个串加多少,范围是
−m到n
−
m
到
n
时间复杂度
O(nlogn)
O
(
n
l
o
g
n
)