zoukankan      html  css  js  c++  java
  • 【学习笔记】自然数幂和

    温馨提示: 本文文档大小约(11KB).

    引入

    自然数幂和是一个我们从小就耳熟能详的经典问题。定义(S(m,n)=sum^{m}_{i=0} i^n), 显然(S(m,n))为关于(m)的不超过((n+1))次多项式,那么给定(n), 如何快速求出这个多项式的系数?或者给定(m)(n), 如何快速求出(S(m,n))? 这就是本文的讨论内容。

    本文介绍三种最常用的方法——拉格朗日插值法、第二类斯特林数法和伯努利数法,这三种方法在解决不同的问题上各有优劣。
    当然,还有一些其他的方法,例如组合数递推法、差分斯特林数法等等,本文略过。

    符号约定

    (x^{underline n})表示(x)(n)次下降幂,即(x^{underline n}=prod^{n}_{i=1}(x-i+1)).

    本文中提到的所有(i), 与虚数均无关系。

    本文中所有运用数学归纳法进行证明的定理,归纳奠基均省略,请读者自行处理。

    拉格朗日(Lagrange)插值法

    概述

    Lagrange插值法的应用范围很广,给定任意((n+1))个互不相同的点值((x_i,y_i)) ((i=0,1,...,n)),其可以在(O(n^2))时间内求出一个不超过(n)次的多项式(f(x)),满足对于任意(i), (f(x_i)=y_i). (“互不相同”指对于任意(0le i<jle n)(x_i e x_j))

    暴力做法

    (f(x_i)=sum^{n}_{i=0} a_ix^i). 根据((n+1))个点值,我们可以列出((n+1))个方程,第(j)个形如(sum^{n}_{i=0}x_j^ia_i=y_j).

    直接高斯消元求解,时间复杂度(O(n^3)).

    插值多项式的唯一性

    定理1 给定任意((n+1))对互不相同的点值((x_i,y_i)),恰好存在一个不超过(n)次的多项式(f(x)),满足对于任意(i), (f(x_i)=y_i).

    证明 根据暴力做法,我们就是要证明方程左边的((n+1) imes (n+1))的系数矩阵可逆。

    实际上系数矩阵就是著名的范德蒙德(Vandermonde)矩阵: (egin{bmatrix} 1&1&1&...&1\ a_0&a_1&a_2&...&a_n\ a_0^2&a_1^2&a_2^2&...&a_n^2\ & & & ... & \ a_0^n&a_1^n&a_2^n&...&a_n^nend{bmatrix})

    可以证明,该矩阵行列式为(prod_{0le i<jle n} (a_j-a_i)).

    考虑数学归纳法,自下而上每一行减去上一行的(a_0)倍,该矩阵变为

    [egin{bmatrix}1&1&1&...&1\ 0&a_1-a_0&a_2-a_0&...&a_n-a_0\ 0&a_1(a_1-a_0)&a_2(a_2-a_0)&...&a_n(a_n-a_0)\&&&...&\0&a_1^{n-1}(a_1-a_0)&a_2^{n-1}(a_2-a_0)&...&a_n^{n-1}(a_n-a_0)end{bmatrix} ]

    然后对第一列展开,每一行提取公因式之后可得(|V|=|V'|prod^{n}_{i=1}(a_i-a_0)), 其中

    [V'=egin{bmatrix}1&1&...&1\a_1&a_2&...&a_n\a_1^2&a_2^2&...&a_n^2\&&...&\a_1^{n-1}&a_2^{n-1}&...&a_n^{n-1}end{bmatrix} ]

    是一个(n imes n)的Vandermonde矩阵,由归纳知其行列式为(prod_{1le i<jle n}(a_j-a_i)), 故(|V|=prod_{0le i<jle n}(a_j-a_i)), 证毕。

    由上可知,由于任意(1le i<jle n)满足(a_i e a_j), 故该矩阵行列式不为(0).

    任意多项式的插值

    直接给出公式。

    定理2 符合((n+1))个点值((x_i,y_i))的多项式为(f(x)=sum^{n}_{i=0} y_iprod_{0le jle n,j e i}frac{x-x_j}{x_i-x_j}).

    证明 代入(x_k), 当(i e k)时后面的乘法有一项因数是(x-x_k=0), 故该积恒为(0). 当(i=k)时显然值为(y_i). 因此该多项式符合((n+1))个给定点值。

    至于这个公式具体是怎么推出来的,大概是考虑求Vandermonde矩阵的逆矩阵,使用矩阵分块法解决,此处不再赘述。

    有了这个公式,我们可以先预处理出(prod^n_{i=0}(x-x_i))的每一项系数(这是一个((n+1))次多项式),然后对于每个(i)暴力用这个多项式除以((x-x_i)). 由于多项式除以一次式可在(O(n))时间内完成,该算法时间复杂度为(O(n^2)).

    使用FFT最好可以做到(O(nlog ^2n)), 但是我不会。

    那么对于自然数幂和问题,我们可以求出(S(m,n))(0,1,2,...,n)处的点值,然后利用Lagrange插值求出这个((n+1))次多项式的每一项系数,时间复杂度(O(n^2)). 如果给定一个(m)要求(S(m,n))的值,那么可以直接把(n)代入多项式求值,时间复杂度(O(n^2)-O(n)) (分别表示预处理和单次询问复杂度), 与(m)无关。

    对于自然数幂和问题的优化

    如果给定(m,n)要求(S(m,n)), 不需要求出多项式每一项的系数,是否可以做到更优的复杂度?(假设(n>k))

    (f(n)=sum^{m}_{i=0}y_iprod_{0le jle n, j e i}frac{n-j}{i-j}=sum^{m}_{i=0}y_ifrac{prod_{0le jle n}(m-j)}{prod_{0le jle n,j e i}(i-j) imes (m-i)}), 可以用阶乘和逆元之类的方法优化,时间复杂度(O(nlog n)-O(n))(O(n)-O(n)).

    第二类斯特林(Stirling)数法

    概述

    第二类斯特林数是一类重要的计数序列,又称“斯特林子集数”,其定义为(egin{Bmatrix}n\kend{Bmatrix})表示将(n)个有编号的物品放入(k)个无编号的集合中,每个集合都非空的方案数。

    由定义可以得出其递推式: (egin{Bmatrix}n\kend{Bmatrix}=kegin{Bmatrix}n-1\kend{Bmatrix}+egin{Bmatrix}n-1\k-1end{Bmatrix}). 考虑最后一个物品,如果将其单独放入一个集合中,则方案数为(egin{Bmatrix}n-1\k-1end{Bmatrix}), 否则所有集合都已经有元素了,所以要加以区分,放入不同的集合算不同的方案,方案数为(kegin{Bmatrix} n-1\kend{Bmatrix}).

    下面两个重要公式给出了第二类Stirling数与幂运算之间的关系。

    定理3 (m^n=sum^{n}_{i=0} egin{Bmatrix}n\iend{Bmatrix}m^{underline i}).

    证明 我们可以从代数和组合等不同角度来证明。

    证法一 代数做法: 考虑使用数学归纳法。对(n)施归纳,

    [m^{n+1}=sum^{n}_{i=0}megin{Bmatrix}n\iend{Bmatrix}m^{underline i}\ =sum^{n}_{i=0}(m-i)egin{Bmatrix}n\iend{Bmatrix}m^{underline i}+sum^{n}_{i=0}iegin{Bmatrix}n\iend{Bmatrix}m^{underline i}\ =sum^{n}_{i=0}egin{Bmatrix}n\iend{Bmatrix}m^{i+1}+sum^{n}_{i=0}iegin{Bmatrix}n\iend{Bmatrix}m^{underline i}\ =sum^{n+1}_{i=1}egin{Bmatrix}n\i-1end{Bmatrix}m^{underline i}+sum^{n}_{i=0}iegin{Bmatrix}n\iend{Bmatrix}m^{underline i}\ =sum^{n+1}_{i=0}egin{Bmatrix}n+1\iend{Bmatrix}m^{underline i} ]

    证法二 组合做法: (m^n)相当于把(n)个有标号数放入(m)个有标号集合的方案数。这些集合有的是空集,有的是非空集合,考虑枚举有多少个非空集合,先从有标号集合里有顺序地选出这(i)个非空集合(方案数(m^{underline i})), 再计算(n)个数放进去的方案数。

    定理4 (egin{Bmatrix}n\mend{Bmatrix}=frac{1}{m!}sum^{m}_{i=0}(-1)^iegin{pmatrix}m\iend{pmatrix}(m-i)^n)

    证明 组合意义上相当于上式套容斥,代数意义上相当于上式套二项式反演。

    根据定理4,我们发现固定(n)之后可以用FFT在(O(nlog n))时间内对每个(m)求出第二类斯特林数。

    分别构造多项式(F(x)=sum_{ige 0}frac{(-1)^i}{i!}x^i)(G(x)=sum_{ige 0}frac{i^n}{i!}x^i), 卷积相乘即可。

    利用第二类斯特林数求自然数幂和

    定理4指出一种快速求第二类斯特林数的方法,而定理3指出第二类斯特林数与自然数的幂的联系。

    既然定理3的式子是把通常幂转化为下降幂,那么求自然数下降幂的和是否容易一些呢?

    这是一个小学数学问题。

    [sum^{m}_{i=0}i^{underline n}=frac{1}{n+1}sum^{m}_{i=0}(i+1)^{underline {n+1}}-i^underline {n+1}=frac{(m+1)^{underline {n+1}}-0^{underline {n+1}}}{n+1}=frac{1}{n+1}(m+1)^{underline {n+1}} ]

    那么考虑将自然数幂和转化为自然数下降幂和:

    [S(m,n)=sum^{m}_{i=0}i^n=sum^{m}_{i=0}sum^{n}_{j=0}egin{Bmatrix}n\jend{Bmatrix}i^{underline j}=sum^{n}_{j=0}egin{Bmatrix}n\jend{Bmatrix}sum^{m}_{i=0}i^{underline j}=sum^{n}_{j=0}frac{1}{j+1}egin{Bmatrix}n\jend{Bmatrix}(m+1)^{underline {j+1}} ]

    于是我们得到了一种通过第二类斯特林数求自然数幂和的方法。如果(n)不固定,那么可以(O(n^2))预处理第二类斯特林数;如果(n)固定,那么可以(O(nlog n))求第二类斯特林数一整行。求出第二类斯特林数之后,可以在不超过(O(nlog P))的时间复杂度内求出(S(m,n)), 其中(P)为模数,(O(log P))为求乘法逆元的复杂度。

    特别地,如果模数性质不好,没法求逆元怎么办?此时Lagrange插值法失去了用武之地,而该方法依然可用,但时间复杂度退化为(O(n^2)). 我们只需要求((j+1))的逆元,而((m+1)^{underline {j+1}})是把((j+1))个连续整数相乘,肯定有一个是((j+1))的倍数,每次找到那个倍数即可。

    伯努利(Bernoulli)数法

    注意在这一部分中,我们需要改变(S(m,n))的定义。现在(S(m,n))定义为(sum^{m-1}_{i=0}i^n), 即比原来少了(m^n).

    概述

    伯努利数法与上面两种方法的适用对象有所不同。伯努利数法适用于对于某个固定的(m), 以及(1)(N)内的所有的(n), 求出(S(m,n))的值, 时间复杂度可以做到(O(nlog n)).

    伯努利数本身就是由伯努利观察自然数幂和的过程中发现的。他对于较小的(n)求出了(S(m,n))多项式的每一次项的系数,然后发现((n+1))次系数总是(1), 对于(0le kle n), ((n-k))次项系数总是等于一个常数乘以(n)的一个下降幂。于是他定义了伯努利数。

    伯努利数(B_n)由以下递归关系定义: (sum^{n}_{i=0}{n+1choose i}B_i=[n=0]). 伯努利数的前(5)项是: (B_0=0, B_1=-frac{1}{2},B_2=frac{1}{6},B_3=0,B_4=-frac{1}{30},B_5=0).

    定理5 伯努利数的指数生成函数(EGF)为(B(x)=sum_{nge 0}frac{B_n}{n!}=frac{x}{e^x-1}).

    证明

    [sum^{n}_{i=0}{n+1choose i}B_i=[n=0]\sum^{n+1}_{i=0}{n+1choose i}B_i=B_{n+1}+[n=0]\sum^{n}_{i=0}{nchoose i}B_i=B_n+[n=1]\frac{B_n}{n!}+[n=1]=sum^{n}_{i=0}frac{1}{(n-i)!}frac{B_i}{i!}\B(x)+x=B(x)e^x\B(x)=frac{x}{e^x-1} ]

    由此,用FFT多项式求逆就可以在(O(nlog n))时间内预处理伯努利数前(n)项。

    利用伯努利数求自然数幂和

    定理6 伯努利数满足关系式(S(m,n)=frac{1}{n+1}sum^{n}_{i=0}{n+1choose i}B_im^{n+1-i}).

    证明 考虑固定(m), 写出(S(m,n))的指数生成函数(S_m(x)).

    [S_m(x)=sum_{nge 0}S(m,n)frac{x^n}{n!}\ =sum_{nge 0}sum^{m-1}_{i=0}i^nfrac{x^n}{n!}\=sum^{m-1}_{i=0}sum_{nge 0}frac{i^n}{n!}x^n\=sum^{m-1}_{i=0}e^{ix}\=frac{e^{mx}-1}{e^x-1}\=B(x)frac{e^{mx}-1}{x}\=B(x)sum_{nge 0}frac{m^{n+1}}{(n+1)!}x^n\ [x^n]S_m(x)=sum^{n}_{i=0}frac{B_i}{i!}frac{m^{n+1-i}}{(n+1-i)!} ]

    然后由于是指数生成函数所以(S(m,n)=n![x^n]S_m(x)), 证毕。

    那么,我们用与上面几例类似的方法,可以用FFT在(O(Nlog N))时间内对固定的(m)和每个(n=1,2,...,N)求出(S(m,n)).

    三种方法的比较

    三种方法适用的问题形式不同,各自的效率也有优劣。

    当数据范围可以接受(O(n^2))的时间复杂度时,三种做法都可以不用FFT实现,代码难度都较小。

    求出多项式的每一次项系数,这是Lagrange插值法的专长。

    当固定(n)不固定(m)时,Lagrange插值法和第二类Stirling数法较为适用。

    当固定(m)不固定(n)时,Bernoulli数法较为适用。

    当模数性质不好无法求逆元时,Stirling数法是较好的选择。

    解决有关具体问题时,一定要注意具体的限制(比如询问形式、询问次数、(n,m)的大小、是否固定),选择较好的方法。

  • 相关阅读:
    uva558 Wormholes SPFA 求是否存在负环
    管理经验(一)——怎样当好一个管理者
    41. 百度面试题:字符串的排列(字符串)
    24L01/SI24R1调试笔记
    中英文对照 —— 学术概念
    matlab 稀疏矩阵(sparse matrix)
    matlab 稀疏矩阵(sparse matrix)
    matlab 可变参数与默认参数设置
    matlab 可变参数与默认参数设置
    卷积、卷积矩阵(Convolution matrix)与核(Kernel)
  • 原文地址:https://www.cnblogs.com/suncongbo/p/11257800.html
Copyright © 2011-2022 走看看