求解自然数幂和的n种方法

版权声明:蒟蒻写的文章,能看就行了,同时欢迎大佬们指点错误 https://blog.csdn.net/Algor_pro_king_John/article/details/86662221

问题的引入

给定 n , k n,k i = 1 n i k \sum_{i=1}^ni^k

1. 循环

四年级应该会循环了。

能做到 O ( n k ) O(nk) 的优秀时间复杂度。

2. 快速幂

五年级学了快速幂之后就能做到 O ( n l o g 2 k ) O(nlog_2k)

请不要小看这个算法。有时候在特定的情况下(例如 n n 很小,或 1 n 1\rightarrow n 的距离变得很小时),这个复杂度真的很优秀。

3. 差分法

六年级应该知道差分和二项式定理了。那么: ( a + 1 ) k a k = i = 0 k 1 C k i a i (a+1)^k-a^k=\sum_{i=0}^{k-1}C_k^ia^i

于是:
( n + 1 ) k 1 = i = 1 n ( i + 1 ) k i k                  = i = 1 n j = 0 k 1 C k j i j                    = i = 0 k 1 C k i j = 1 n j i                = i = 0 k 1 C k i S ( i ) (n+1)^k-1 =\sum_{i=1}^n (i+1)^k-i^k \\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\sum_{i=1}^n\sum_{j=0}^{k-1}C_k^ji^j\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\sum_{i=0}^{k-1}C_k^i\sum_{j=1}^n j^i\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =\sum_{i=0}^{k-1}C_k^i S(i) ( n + 1 ) k + 1 1 = i = 0 k C k + 1 i S ( i ) \therefore (n+1)^{k+1}-1=\sum_{i=0}^kC_{k+1}^iS(i)

i = k i=k 时移项,可以得到 ( k + 1 ) S ( k ) = ( n + 1 ) k + 1 1 i = 0 k 1 C k + 1 i S ( i ) (k+1)S(k)=(n+1)^{k+1}-1-\sum_{i=0}^{k-1}C_{k+1}^iS(i)

所以 S ( k ) = ( n + 1 ) k + 1 1 i = 0 k 1 C k + 1 i S ( i ) k + 1 S(k)=\frac{(n+1)^{k+1}-1-\sum_{i=0}^{k-1}C_{k+1}^iS(i)}{k+1}

同时仔细观察这个式子,我们发现, k k 次方和的求和公式是 k + 1 k+1 次的。归纳证明即可。

3. 倍增

初一应该会倍增了,所以我们令 f n , k = i = 1 n i k f_{n,k}=\sum_{i=1}^ni^k

n n 是奇数的时候直接由 f n 1 , k + n k f_{n-1,k}+n^k 转移过来。偶数的时候拆开来,运用简单的二项式定理,一波式子推得: f ( n , k ) = f ( n 2 , k ) + j = 0 k C k j f ( n 2 , j ) n 2 k j f(n,k)=f(\frac{n}{2},k)+\sum_{j=0}^kC_k^j*f(\frac{n}{2},j)*\frac{n}{2}^{k-j}

每一层的 f n , k f_{n,k} 我们计算的时间复杂度都是 O ( k 2 ) O(k^2) 的, l o g n log_n 层,时间复杂度 O ( k 2 l o g n ) O(k^2log_n) .

4. 高斯消元

初一应该会高斯消元了。这是个大脑洞。虽然时间复杂度比上一个还劣一些。

根据 k k 次方和的求和公式是 k + 1 k+1 次的,所以列出 k + 2 k+2 条式子就可以唯一确定这个多项式。

时间复杂度 O ( k 3 ) O(k^3) .

5. 第一类斯特林数

初二来学习一下斯特林数。

第一类斯特林数我们一般清楚的是它的组合意义,即把 n n 个元素分成 k k 个圆排列的方案。根据组合意义,我们不难推出它的式子是 S u ( n , m ) = S u ( n 1 , m 1 ) + ( n 1 ) S u ( n 1 , m ) S_u(n,m)=S_u(n-1,m-1)+(n-1)S_u(n-1,m)

但事实上,我们求解自然数幂和需要用到的是它的原始定义
x n = x ( x 1 ) ( x 2 ) ( x n + 1 ) = k = 0 n s s ( n , k ) x k x^{n\downarrow}=x\cdot (x-1)\cdot (x-2)\cdots (x-n+1)=\sum_{k=0}^ns_s(n,k)\cdot x^k x n = x ( x + 1 ) ( x + 2 ) ( x + n 1 ) = k = 0 n s u ( n , k ) x k x^{n\uparrow}=x\cdot (x+1)\cdot (x+2)\cdots(x+n-1)=\sum_{k=0}^ns_u(n,k)\cdot x^k

这里需要注意,第一类斯特林数根据定义分成了有符号 S s S_s 和无符号 S u S_u 两种。事实上,我们可以很轻松的从这个原始定义推出它的组合意义

因为 k = 0 n S u ( n , k ) x k = x n = x ( n 1 ) ( x + n 1 ) \sum_{k=0}^nS_u(n,k)·x^k=x^{n\uparrow}=x^{(n-1)\uparrow}·(x+n-1) = k = 0 n 1 S u ( n 1 , k ) x k + 1 + ( n 1 ) k = 0 n 1 S u ( n 1 , k ) x k =\sum_{k=0}^{n-1}S_u(n-1,k)x^{k+1}+(n-1)\sum_{k=0}^{n-1}S_u(n-1,k)x^k

对比两边 x m x^m 的系数,可以得到 S u ( n , m ) = S u ( n 1 , m 1 ) + ( n 1 ) S u ( n 1 , m ) S_u(n,m)=S_u(n-1,m-1)+(n-1)S_u(n-1,m) 继续推有符号的,可以得到 S s ( n , m ) = S s ( n 1 , m 1 ) ( n 1 ) S s ( n 1 , m ) S_s(n,m)=S_s(n-1,m-1)-(n-1)S_s(n-1,m) 事实上,我们可以完全不用记第一类斯特林数的组合意义,通过公式直接推出来即可。当然记了更好,还可以验证。

所以,根据第一类斯特林数的的定义,得到: x = 0 k 1 ( n x ) = k = 0 n S s ( n , k ) x k \prod_{x=0}^{k-1}(n-x)=\sum_{k=0}^nS_s(n,k)x^k

于是我们可以得到一个显然的式子是: n m = n m k = 0 m 1 S s ( m , k ) n k n^m=n^{m\downarrow}-\sum_{k=0}^{m-1}S_s(m,k)·n^k

我们继续推,发现下降幂的和是可以写成一个组合数的形式的,比方说 i = m n i m = i = m n i ! m ! ( i m ) ! m ! = m ! i = m n ( i m ) = m ! ( n + 1 m + 1 ) \sum_{i=m}^ni^{m\downarrow}=\sum_{i=m}^n\frac{i!m!}{(i-m)!m!}=m!\sum_{i=m}^n\binom{i}{m}=m!\binom{n+1}{m+1}

而后面那一坨式子也是可以化简的,比方说 i = 0 n k = 0 m 1 S s ( m , k ) i k = k = 0 m 1 S s ( m , k ) i = 0 n i k \sum_{i=0}^n\sum_{k=0}^{m-1}S_s(m,k)·i^k=\sum_{k=0}^{m-1}S_s(m,k)\sum_{i=0}^ni^k

发现后面那条式子 i = 0 n i k \sum_{i=0}^ni^k k k 是降了阶的,所以可以边处理边记录一下,就不用重新算了,时间复杂度就变成了 O ( k 2 ) O(k^2) 。而处理 S s ( m , k ) S_s(m,k) 也是 O ( k 2 ) O(k^2) 级别。

事实上如果当你升入初三, S s ( m , k ) S_s(m,k) 就可以运用分治 N T T NTT 做到 O ( k l o g 2 k ) O(klog^2k) 了,虽然然并卵。

但请注意,这种方法虽然时间复杂度是 O ( k 2 ) O(k^2) 级别的,但是它并非没有什么用,因为它——不用做除法

6. 第二类斯特林数

第二类斯特林数的组合意义就是 n n 个元素分成 m m 个集合,且集合非空的方案数。

基本性质是 { n m } = { n 1 m 1 } + m { n 1 m } \begin{Bmatrix}n\\m\end{Bmatrix}=\begin{Bmatrix}n-1\\m-1\end{Bmatrix}+m\cdot \begin{Bmatrix}n-1\\m\end{Bmatrix}

考虑它的通项公式,可以先把所有集合标号,最后除以集合的阶乘即可,那么考虑容斥,枚举非空集合个数 i i ,可以得到 { n m } = 1 m ! i = 0 m ( 1 ) i ( m i ) ( m i ) n \begin{Bmatrix}n\\m\end{Bmatrix}=\frac 1 {m!}\sum_{i=0}^m(-1)^i\binom mi(m-i)^n

接下来继续推导自然数幂和。

显然!! i k = j = 0 k { k j } i j i^k=\sum_{j=0}^k\left\{\begin{array}{c}{k}\\{j}\end{array}\right\}i^{j\downarrow}

继续推导 i = 1 n i k = i = 1 n j = 0 k { k j } i j \sum_{i=1}^ni^k=\sum_{i=1}^n\sum_{j=0}^k\left\{\begin{array}{c}{k}\\{j}\end{array}\right\}i^{j\downarrow} = i = 1 n j = 0 k { k j } j ! ( i j ) =\sum_{i=1}^n\sum_{j=0}^k\left\{\begin{array}{c}{k}\\{j}\end{array}\right\} j!\left(\begin{array}{c}{i}\\{j}\end{array}\right) = j = 0 k { k j } j ! i = j n ( i j ) =\sum_{j=0}^k\left\{\begin{array}{c}{k}\\{j}\end{array}\right\} j!\sum_{i=j}^n\left(\begin{array}{c}{i}\\{j}\end{array}\right) = j = 0 k { k j } j ! ( n + 1 j + 1 ) =\sum_{j=0}^k\left\{\begin{array}{c}{k}\\{j}\end{array}\right\} j!\binom{n+1}{j+1}

很明显,除去预处理第二类斯特林数的复杂度,后面是一样不用做除法的,可以做到 O ( k ) O(k) .

那么时间复杂度决定于预处理第二类斯特林数的复杂度。显然可以用 O ( k 2 ) O(k^2) 递推。

然而事实上,我们来看看斯特林数的通项公式: { n m } = 1 m ! i = 0 m ( 1 ) i ( m i ) ( m i ) n \begin{Bmatrix}n\\m\end{Bmatrix}=\frac 1 {m!}\sum_{i=0}^m(-1)^i\binom mi(m-i)^n

一拼凑,咦~ { n m } = i = 0 m ( 1 ) i i ! ( m i ) n ( m i ) ! \begin{Bmatrix}n\\m\end{Bmatrix}=\sum_{i=0}^m\frac{(-1)^i}{i!}\cdot\frac{(m-i)^n}{(m-i)!}

这原来可以写成形如 i = 0 m f ( i ) g ( m i ) \sum_{i=0}^mf(i)*g(m-i) 的卷积形式。于是第一个多项式的第 i i 项系数是 ( 1 ) i i ! \frac {(-1)^i}{i!} ,另一个多项式的第 i i 项系数是 i n i ! \frac {i^n}{i!} ,卷积后第 i i 项的系数就是 { n i } \begin{Bmatrix}n\\i\end{Bmatrix} .

于是愉快的将时间变成了 O ( K l o g K ) O(KlogK)

7. 差分表

初三来学习一下差分表吧。

对于任何一个序列 a 0 , a 1 , . . . , a n , . . . a_0, a_1, ... , a_n, ... 我们都可以定义它的差分序列 Δ a 0 , Δ a 1 , . . . , Δ a n , . . . \Delta a_0, \Delta a_1, ... ,\Delta a_n, ... ,其中 Δ a i = a i + 1 a i \Delta a_i=a_{ i+1 }-a_i

类似的,我们可以构造序列 { Δ a n } \{\Delta a_n\} 的二阶、三阶… k k 阶差分序列。 不妨记为 { Δ 2 a n } , . . . , { Δ k a n } \{\Delta^2 a_n\},...,\{\Delta^k a_n\}

令序列是一个 p p 次多项式,那么差分表一个很重要且很显然的性质是: n > = 0 , Δ p + 1 a n = 0 \forall n>=0, \Delta^{p+1}a_n = 0 这是由于每次差分都必然会把最高次项消去!

另外一个很重要的性质就是差分表的线性性,即如果 f n = k 1 g n + k 2 h n f_n=k_1g_n+k_2h_n ,那么一定有 p , n , Δ p f n = k 1 Δ p g n + k 2 Δ p h n \forall p, n, \Delta^p f_n=k_1\Delta^p g_n + k_2\Delta^p h_n

而其最重要的一个性质就是,任何一个 p p 阶多项式,都必定可以由其差分表的第一条对角线确定。为了证明这个结论,不妨先考虑最简单的情况:

差分表的一条对角线为 0 , . . . , 0 , 1 , 0 , . . . 0, ..., 0, 1, 0, ... ,即第一条对角线上只有第 p p 个位置为 1 1 ,其他都为 0 0 ,那么可以写出这个序列的通项公式 f n = c ( n ) ( n 1 ) ( n 2 ) . . . ( n p + 1 ) f_n=c(n)(n-1)(n-2)...(n-p+1)

代入 n = p , f p = 1 n=p,f_p=1 ,得到 c = 1 p ! c=\frac{1}{p!} 所以可以得到 f n = n ! p ! ( n p ) ! = ( n p ) f_n=\frac{n!}{p!(n-p)!}=\tbinom{n}{p}

那么根据差分表的线性性,我们就可以得知 f n = i = 0 p c i ( n i ) f_n=\sum_{i=0}^p c_i\tbinom{n}{i}
由于 k = 0 n f ( k ) = k = 0 p c k ( n + 1 k ) \sum_{k = 0}^n f(k) = \sum_{k = 0}^p c_k {n + 1 \choose k} 所以利用差分表,我们可以在 O ( p 2 ) O(p^2) 的时间复杂度求解类似于 i = 0 n f i \sum_{i=0}^n f_i 的式子。

回到自然数幂和的问题上,我们把 f i = i k f_i=i^k 代入计算前 p p 项的值,通过 p 2 p^2 的时间复杂度处理出差分表的第一条对角线,设这个对角线为 c ( p , 0 ) , c ( p , 1 ) , c ( p , 2 ) , , c ( p , p ) c(p, 0), c(p, 1), c(p, 2), \dots, c(p, p) ,那么答案就是 k = 0 p c ( p , k ) ( n + 1 k ) \sum_{k = 0}^p c(p, k){n + 1 \choose k}

8. 伯努利数

初三再来学一学伯努利数吧。

根据伯努利数的生成函数定义,可知 x e x 1 = i 0 B i x i i ! \frac{x}{e^{x}-1} = \sum_{i\geq 0} B_{i}*\frac{x^{i}}{i!}

由于 x e x 1 ( e x 1 ) = x \frac{x}{e^x-1}·(e^x-1)=x

[ x n ] x e x 1 ( e x 1 ) = i = 0 n 1 B i i ! 1 ( n i ) ! = [ n = 1 ] [x^n]\frac{x}{e^x-1}·(e^x-1)=\sum_{i=0}^{n-1}\frac{B_i}{i!}·\frac{1}{(n-i)!}=[n=1]

两边都乘上 n ! n! 可以得到 i = 0 n 1 ( n i ) B i = [ n = 1 ] \sum_{i=0}^{n-1}\binom{n}{i}B_i=[n=1]

这是伯努利数的一个基本性质。后面会用到。

我们再定义一个多项式 B n ( t ) B_n(t) 表示 B n ( t ) = k = 0 n 1 B k t n k C n k B_{n}(t) = \sum_{k=0}^{n-1} B_{k} * t^{n-k}*C_{n}^{k}

然后我们发现
B n ( t + 1 ) B n ( t ) = k = 0 n 1 B k ( t + 1 ) n k t n k C n k B_n(t+1)-B_n(t)=\sum_{k=0}^{n-1} B_{k}*\lgroup(t+1)^{n-k} - t^{n-k}\rgroup C_{n}^{k} = k = 0 n 1 B k ( i = 0 n k 1 C n k i t i ) C n k =\sum_{k=0}^{n-1} B_{k}*(\sum_{i=0}^{n-k-1} C_{n-k}^{i} * t^{i})* C_{n}^{k} = k = 0 n 1 B k ( i = 0 n k 1 C n k i t i C n k ) =\sum_{k=0}^{n-1} B_{k}*(\sum_{i=0}^{n-k-1} C_{n-k}^{i} * t^{i}*C_{n}^{k}) = i = 0 n 1 B k i = 0 n k 1 n ! t i i ! k ! ( n k i ) ! =\sum_{i=0}^{n-1}B_k*\sum_{i=0}^{n-k-1}\frac{n!t^i}{i!k!(n-k-i)!} = k = 0 n 1 B k ( i = 0 n k 1 C n i k t i C n i ) =\sum_{k=0}^{n-1} B_{k}*(\sum_{i=0}^{n-k-1} C_{n-i}^{k} * t^{i}*C_{n}^{i}) = i = 0 n 1 C n i t i k = 0 n 1 i B k C n i k =\sum_{i=0}^{n-1} C_{n}^{i}*t^{i}*\sum_{k=0}^{n-1-i} B_{k}*C_{n-i}^{k}

注意到后面只有当 n i 1 = 0 n-i-1=0 时值为 1 1 ,于是 B n ( t + 1 ) B n ( t ) = n t n 1 B_n(t+1)-B_n(t)=n*t^{n-1}

然后我们考虑差分,就有 t = 0 n 1 B k ( t + 1 ) B k ( t ) = k i = 0 n 1 i k 1 \sum_{t=0}^{n-1}B_k(t+1)-B_k(t)=k·\sum_{i=0}^{n-1}i^{k-1} B k + 1 ( n + 1 ) = ( k + 1 ) i = 0 n i k B_{k+1}(n+1)=(k+1)·\sum_{i=0}^ni^k

可得自然数幂和 i = 0 n i k = 1 k + 1 i = 0 k B i n k + 1 i ( k + 1 i ) \sum_{i=0}^ni^k=\frac{1}{k+1}·\sum_{i=0}^kB_in^{k+1-i}\binom{k+1}{i}

问题转化成了求 B i B_i ,注意到它的生成函数定义,事实上我们只需要求 i 0 x i ( i + 1 ) ! \sum_{i\ge 0}\frac{x^i}{(i+1)!} 在模 x k + 1 x^{k+1} 的逆元即可。

时间复杂度 O ( K L o g K ) O(KLogK) ,当然如果递推的话,也是可以轻松做到 O ( k 2 ) O(k^2) 的。

9. 拉格朗日插值法

猜你喜欢

转载自blog.csdn.net/Algor_pro_king_John/article/details/86662221