一年前的 BJ 集训里出现了这样一道题,其中我留下了这样一个疑惑:
计算 ∏ i = 0 n − 1 ( 1 + x i ) m o d ( x n − 1 ) \prod_{i=0}^{n-1} (1+x^i) \bmod (x^n-1) ∏i=0n−1(1+xi)mod(xn−1) 的系数。
当然这个问题的第一个 observation 是非常重要的,即对于 gcd ( n , k ) = g \gcd(n,k)=g gcd(n,k)=g 有相同 g g g 的 k k k,各 k k k 次项系数是相等的。因此我们可以认为这个问题只要求 d ( n ) d(n) d(n) 个 output。
这是因为我们考虑 x → x k x\rightarrow x^k x→xk 的映射,当 gcd ( n , k ) = 1 \gcd(n,k)=1 gcd(n,k)=1 的时候对下标是一个置换,在这个置换下乘积式显然不变,而取遍所有互质的 k k k 的时候每一个 gcd \gcd gcd 相同的下标组则构成一个轨道。
那道题里有个看起来像是 Θ ( n 2 ) \Theta(n^2) Θ(n2) 的瓶颈,所以这部分就 Θ ( n 2 ) \Theta(n^2) Θ(n2) 过了,但是今天这个部分重新拿到我面前的时候,总算经过重新思考,想到了一些有趣的东西。
我们考虑其 DFT 数组,首先不难观察到 DFT 数组也和第一个 observation 是相同的,这是可以考虑根的置换符合这一性质。
因此 D F T [ a ] i \mathbf{DFT}[a]_i DFT[a]i 我们设 gcd ( i , n ) = k \gcd(i,n)=k gcd(i,n)=k,那么这个 DFT 值其实就是
( 1 + ω n k ) ( 1 + ω n 2 k ) ⋯ ( 1 + ω n n k ) = [ ( 1 + ω n k ) ( 1 + ω n 2 k ) ⋯ ( 1 + ω n n k k ) ] k = [ ( 1 + ω n / k ) ( 1 + ω n / k 2 ) ⋯ ( 1 + ω n / k n / k ) ] k \begin{aligned} &\quad (1 + \omega_n^k)(1 + \omega_n^{2k}) \cdots (1 + \omega_n^{nk}) \\ &= \left[(1 + \omega_n^k)(1 + \omega_n^{2k}) \cdots (1 + \omega_n^{\frac nk k})\right]^k\\ &= \left[(1 + \omega_{n/k})(1 + \omega_{n/k}^{2}) \cdots (1 + \omega_{n/k}^{n/k})\right]^k \end{aligned} (1+ωnk)(1+ωn2k)⋯(1+ωnnk)=[(1+ωnk)(1+ωn2k)⋯(1+ωnknk)]k=[(1+ωn/k)(1+ωn/k2)⋯(1+ωn/kn/k)]k
所以我们还是主要要解决 ( 1 + ω n ) ( 1 + ω n 2 ) ⋯ ( 1 + ω n n ) (1+\omega_n)(1+\omega_n^2) \cdots (1+\omega_n^n) (1+ωn)(1+ωn2)⋯(1+ωnn) 是多少,其实我们不妨做变形:
P ( x ) = ( 1 − ω n x ) ( 1 − ω n 2 x ) ⋯ ( 1 − ω n n x ) = 1 − x n P(x) = (1-\omega_n x)(1- \omega_n^2 x) \cdots (1- \omega_n^n x) = 1-x^n P(x)=(1−ωnx)(1−ωn2x)⋯(1−ωnnx)=1−xn
由根系关系,这是显然的,而我们只需带入 x = − 1 x=-1 x=−1,便发现上式的乘积即为 ( 1 − ( − 1 ) n ) = 2 [ n m o d 2 ] (1-(-1)^n) = 2[n\bmod 2] (1−(−1)n)=2[nmod2]
因此对于 gcd ( i , n ) = k \gcd(i,n)=k gcd(i,n)=k 的所有 i i i,我们有
D F T [ a ] i = ( 2 [ n / k m o d 2 ] ) k \mathbf{DFT}[a]_i = (2[n/k \bmod 2])^k DFT[a]i=(2[n/kmod2])k
再做 IDFT 的时候,我们需要考虑相同取值位置的单位根值之和,即
W j ( n / k ) = ∑ gcd ( i , n ) = k ω n i j = ∑ gcd ( i / k , n / k ) = 1 ω n / k i j / k W j ( n ) = ∑ gcd ( i , n ) = 1 ω n i j ∑ k ∣ n W j ( k ) = ∑ 0 ≤ i < n ω n i j = n [ n ∣ j ] \begin{aligned} W_j(n/k) &=\sum_{\gcd(i,n)=k} \omega_n^{ij} \\ &= \sum_{\gcd(i/k,n/k)=1} \omega_{n/k}^{ij/k}\\ W_j(n) &= \sum_{\gcd(i,n)=1} \omega_{n}^{ij}\\ \sum_{k|n} W_j(k) &= \sum_{0\le i < n} \omega_{n}^{ij}\\ &= n[n|j]\\ \end{aligned} Wj(n/k)Wj(n)k∣n∑Wj(k)=gcd(i,n)=k∑ωnij=gcd(i/k,n/k)=1∑ωn/kij/k=gcd(i,n)=1∑ωnij=0≤i<n∑ωnij=n[n∣j]
于是,我们完成了 Θ ( poly n ) \Theta(\operatorname{poly} n) Θ(polyn) 到 Θ ( poly d ( n ) ) \Theta(\operatorname{poly} d(n)) Θ(polyd(n)) 的跨越,剩下的优化有兴趣者可以继续完成。