(也许是)冷门算法——单位根反演

nekko

2018-09-13 19:20:02

Algo. & Theory

(由于太懒不一定)同步于我的博客

前置技能

引入

从一道题说起……

给定n,s,a_0,a_1,a_2,a_3,求

\sum_{i=0}^{n} {n \choose i} s^i a_{i \bmod 4}

答案对998244353取模

1 \le n \le 10^{18}, 1 \le s,a_0,a_1,a_2,a_3 \le 10^8

一脸绝望

在高中的时候,数学老师教会了我们(a+b)^{n}=\sum_{i=0}^{n}{n \choose i}a^{i}b^{n-i},然后惊喜的发现这道题不能这么做!

OI中,我们学习了单位根的基本性质(如果还未学,可从前置技能部分的单位根处点击链接学习),关于单位根还有一个迷之用法——单位根反演

构造生成函数

对于数列a_i,构造其生成函数f(x)=\sum_{i=0}^{n}a_ix^i

现在我们想知道所有下标是k的倍数的a_i的和,既\sum_{i=0}^{n}a_i[k|i]

一个关于[n|k]的等式

有一个关于n次单位根w_n的等式,看起来十分有趣 毒瘤

[n|k]=\frac{1}{n}\sum_{i=0}^{n-1}\omega_n^{ki}

证明

如果n \mid k,设k=np,则

\frac{1}{n}\sum_{i=0}^{n-1}w_n^{npi \bmod n}=\frac{1}{n}\sum_{i=0}^{n-1}w_n^{0}=1

注:npi \bmod n=(n \bmod n) \times (pi \bmod n)=0 \times (pi \bmod n)=0

如果n \nmid k,根据等比数列求和公式,则

\frac{1}{n}\sum_{i=0}^{n-1}\omega_{n}^{ki}=\frac{1}{n}(w_n^{0}\frac{1-\omega_n^{k(n-1)}}{1-w_n^{k}})=\frac{w_n^0-w_n^{kn}}{n(1-\omega_n^{k})}=0

于是对于N次单位根w_N可以这么搞:

\frac{\sum_{i=0}^{N-1}f(w_N^i)}{N}=\frac{\sum_{i=0}^{n}a_i\sum_{j=0}^{N-1}w_N^{ij}}{N}=\sum_{i=0}^{n}a_i[N \mid i]

于是就可以得到所有下标是N的倍数的a_i的和了

有一个问题

但是发现,只知道所有N \mid ia_i的和还不够有用,如果分别知道i \bmod N \in [0,N-1]a_i的和的话就十分有用了

数学老师告诉我们,f(x)通过乘以x的若干次幂可以实现函数的平移(虽然说这句话不太严谨……但还是可以凑合着看看……)

比如说现在有f(x)=a_0x^{0}+a_1x^{1}+a_2x^{2} + \dots

对其乘上x^{-1}后会得到f(x)x^{-1}=a_0x^{-1}+a_1x^{0}+a_2x^{1} + \dots

再用上面的方法求后就得到了N \bmod i = 1的所有a_i

回到例题

在这道题中,构造f(x)=\sum_{i=0}^{n} {n \choose i} s^i x^i 1^{n-i}=(sx+1)^n

则答案为\sum_{i=0}^{3}a_ic_i,其中c_i=\sum\limits_{j=0}^{n}{n \choose j}s^j[j \bmod 4 = i]

对于c_if(\omega_N^j),因为需要将\omega_N^{j}向右平移i次,只需要将其变为\huge \frac{f(\omega_N^j)}{\omega_N^{ij \bmod 4}}即可

扩展到矩阵上

bzoj 3328

题目描述

给定n,k,p,求

\sum_{i=0}^{\lfloor \frac{n}{k} \rfloor} {n \choose ik}F_{ik}

其中F_0=F_1=1,且\forall n \ge 2,F_i=F_{i-1}+F_{i-2}

答案对p取模

1 \le n \le 10^{18} 1 \le k \le 20000 1 \le p \le 10^9 $p \bmod k = 1

题解

单位根反演的结论在矩阵意义上也是成立的

也就是说求

\sum_{i=0}^{n} {n \choose i} F_i [k \mid i]

A是斐波那契数列的转移矩阵,I为单位矩阵

通过套用二项式定理,有

f(x)=(Ax+I)^n=\sum_{i=0}^{n} {n \choose i}A^ix^iI^{n-i}

再套用单位根反演,有

T=\frac{\sum_{i=0}^{k-1}f(\omega_k^i)}{k}

然后就做完了,答案就是矩阵T的左上角

总结

如果想计算序列a_0, a_1,a_2, \dots , a_n的所有满足k|ia_i的和的话

首先构造f(x)=\sum_{i=0}^{n}a_ix^i

然后将\omega_k^i(i \in [0,k-1])依次代入到f(x)中,并求和

最后除以k即可

也就是说

\sum_{i=0}^{n}a_i[k|i]=\frac{1}{k}\sum_{i=0}^{k-1}f(\omega_k^i)

参考文献

Zhang-RQ 单位根反演学习笔记

shadowice1984 loj6485 LJJ学二项式定理

DT_Kang 【4.13 提高班小记】单位根&&杂题

Mys_C_K [真学习笔记] 前夕 - 单位根反演 - 广义容斥

Regina8023 【BZOJ 3328】PYXFIB