FFT

https://en.wikipedia.org/wiki/Fast_Fourier_transform

多项式

n次多项式,n+1个系数
(a[0] + a[1] * x + a[2] * x^2 + .. + a[n] * x^n)
(b[0] + b[1] * x + b[2] * x^2 + .. + b[n] * x^n)

A * B = C
c[0] = a[0] * b[0]
c[1] = a[1] * b[0] + a[0] * b[1]
c[2] = a[2] * b[0] + a[1] * b[1] + a[0] * b[2]
...

暴力 O(n^2)
FFT O(n log n)

离散傅里叶变换
连续傅里叶变换(和我们做的比赛没什么关系)

复数

找到l个点,l是2的次幂,对2个多项式求值

通过一个算法 求值
A(0) == ..
A(1) == ..
..
A(l-1) == ..

B(0) == ..
B(1) == ..
..
B(l-1) == ..

对应的位置乘起来
C(0) == A(0) * B(0)

C(i) == A(i) * B(i)
..

根据
C(0) C(1) C(...)
推回多项式的系数

复数的乘法
模长相乘,幅角相加

2类

  1. 用复数 / 用double FFT

  2. 用数论 / 取模,用原根 NTT

a[0] + a[1] x + a[2] x^2 + a[3] x^3

w_n 是 n次单位根 (w_n)^n = 1 以下用 w
n = 4
w^n = 1
w^{n/2} = -1

b[0] = A(w^0) = a[0] * w^0 + a[1] * w^0 + a[2] * w^0 + a[3] * w^0
b[1] = A(w^1) = a[0] * w^0 + a[1] * w^1 + a[2] * w^2 + a[3] * w^3
b[2] = A(w^2) = a[0] * w^0 + a[1] * w^2 + a[2] * w^0 + a[3] * w^2
b[3] = A(w^3) = a[0] * w^0 + a[1] * w^3 + a[2] * w^2 + a[3] * w^1

a[0] = (b[0] * w^0 + b[1] * w^0 + b[2] * w^0 + b[3] * w^0) / 4
a[3] = (b[0] * w^0 + b[1] * w^1 + b[2] * w^2 + b[3] * w^3) / 4
a[2] = (b[0] * w^0 + b[1] * w^2 + b[2] * w^0 + b[3] * w^2) / 4
a[1] = (b[0] * w^0 + b[1] * w^3 + b[2] * w^2 + b[3] * w^1) / 4

a[0]
a[2]
a[1]
a[3]

a[0] * w^0 + a[2] * w^0
a[0] * w^0 + a[2] * w^2
a[1] * w^0 + a[3] * w^0
a[1] * w^0 + a[3] * w^2

a[0] * w^0 + a[2] * w^0 + a[1] * w^0 + a[3] * w^0
a[0] * w^0 + a[2] * w^2 + a[1] * w^1 + a[3] * w^3 = a'[1] + a'[3] * w
a[0] * w^0 + a[2] * w^0 + a[1] * w^2 + a[3] * w^2
a[0] * w^0 + a[2] * w^2 + a[1] * w^3 + a[3] * w^1 = a'[1] - a'[3] * w

n=8
A(w^0) = a[0] * w^0 + a[1] * w^0 + a[2] + a[3] + a[0]
A(w^1) = a[0] + a[1] * w + a[2] * w^2 + a[3] * w^3
A(w^2) = a[0] + a[1] * w^2 + a[2] + a[3] * w^2
A(w^3) = a[0] + a[1] * w^3 + a[2]^2 + a[3] * w
A(w^4) = a[0] + a[1] * w^3 + a[2]^2 + a[3] * w
A(w^5) = a[0] + a[1] * w^3 + a[2]^2 + a[3] * w
A(w^6) = a[0] + a[1] * w^3 + a[2]^2 + a[3] * w
A(w^7) = a[0] + a[1] * w^3 + a[2]^2 + a[3] * w

a[0]
a[1]
a[2]
a[3]
a[4]
a[5]
a[6]
a[7]

1 -> 001
4 -> 100

a[0]
a[4]
a[2]
a[6]
a[1]
a[5]
a[3]
a[7]

a[0] * w^0 + a[4] * w^0
a[0] * w^0 + a[4] * w^4
a[2] * w^0 + a[6] * w^0
a[2] * w^0 + a[6] * w^4
a[1] * w^0 + a[5] * w^0
a[1] * w^0 + a[5] * w^4
a[3] * w^0 + a[7] * w^0
a[3] * w^0 + a[7] * w^4

a' 表示上一组

a[0] * w^0 + a[4] * w^0 + a[2] * w^0 + a[6] * w^0 (a'[0] + a'[2] * w^0)
a[0] * w^0 + a[4] * w^4 + a[2] * w^2 + a[6] * w^6 (a'[1] + a'[3] * w^2)
a[0] * w^0 + a[4] * w^0 + a[2] * w^4 + a[6] * w^4 (a'[0] + a'[2] * w^4)
a[0] * w^0 + a[4] * w^4 + a[2] * w^4 + a[6] * w^2 (a'[1] + a'[3] * w^6)

http://lydsy.com/JudgeOnline/problem.php?id=3513
x^j的系数,是j在a数组中出现的次数

给定n个长度分别为a_i的木棒,问随机选择3个木棒能够拼成三角形的概率。
问概率 = 问方案数
全部 - 不能
不能 = (最大的 >= 较小的2个)
枚举最大的是谁,在所有中选取不同的2个,不考虑顺序,和小于等于最大的方案数

(.. x^j ..)^2 之后的 j 次方的系数就是从a数组中选取2个数字(考虑顺序,可以重复)和为j的方案数

http://www.51nod.com/Challenge/Problem.html#problemId=1030
高精度进制转换

bzoj 3160
万径人踪灭

bzoj 5217
航海舰队

bzoj 3992
序列统计

http://poj.openjudge.cn/campus2014/D/
Colorful World

n = 4

a[0] a[3] a[2] a[1]
a[1] a[0] a[3] a[2]
a[2] a[1] a[0] a[3]
a[3] a[2] a[1] a[0]

a[0] a[1] a[2] a[3]

p[0] p[1] p[2] p[3]

q[0] = a[0] * p[0]
q[1] = a[0] * p[1] + a[1] * p[0]
q[2] = a[0] * p[2] + a[1] * p[1] + a[2] * p[0]
q[3] = a[0] * p[3] + a[1] * p[2] + a[2] * p[1] + a[3] * p[0]
q[4] = a[1] * p[3] + a[2] * p[2] + a[3] * p[1]
q[5] = a[2] * p[3] + a[3] * p[2]
q[6] = a[3] * p[3]

q[0] = a[0] * p[0] + a[1] * p[3] + a[2] * p[2] + a[3] * p[1]
q[1] = a[0] * p[1] + a[1] * p[0] + a[2] * p[3] + a[3] * p[2]
q[2] = a[0] * p[2] + a[1] * p[1] + a[2] * p[0] + a[3] * p[3]
q[3] = a[0] * p[3] + a[1] * p[2] + a[2] * p[1] + a[3] * p[0]

经过
(1, 1) (2, 8) (3, 27) 的二次多项式是什么
x^3 % ((x-1)(x-2)(x-3)) 是什么?

https://www.codechef.com/problems/FARASA
数多少个不同的部分和,根据数据大小分类讨论

https://www.codechef.com/problems/COUNTARI
数i, j, k等差数列个数,分块FFT

https://www.codechef.com/problems/PRIMEDST
树上距离为质数的点对

https://www.spoj.com/problems/OVICUMSUM/
前缀和 FFT 组合数

luogu P5488
前缀和 FFT 组合数

A * B * C

FFT(A, 1)
FFT(B, 1)
AB = A * B
FFT(C, 1)
ABC = AB * C
FFT(ABC, -1)

FFT做多项式运算
  1. FFT