专题——自然数幂和 详解

自然数幂和,有许多种解决方法,其中最典型的有下面几种。

Description

∑ i = 1 n i k \sum_{i=1}^n i^k i=1nik

由于答案可能过大,请将其对 1 0 9 + 7 10^9+7 109+7取模。

法1: 暴力

时间复杂度 O ( n log ⁡ k ) O(n \log k) O(nlogk)

法2: 线性筛

不难发现 f ( i ) = i k f(i)=i^k f(i)=ik完全积性函数

于是我们直接线性筛即可。时间复杂度为 O ( n ln ⁡ n log ⁡ k + n ) O(\frac {n \ln n} {\log k}+n) O(logknlnn+n) ,类线性。

法3: 高斯消元

可以发现,答案是一个 k + 1 k+1 k+1次多项式,即 ∑ i = 1 n i k = ∑ i = 0 k + 1 f i   n i \sum_{i=1}^n i^k=\sum_{i=0}^{k+1} f_i\ n^i i=1nik=i=0k+1fi ni

现在关键在于如何求出 f i f_i fi。我们可以令 i = 1 , 2 … … k + 2 i=1,2……k+2 i=1,2k+2,分别得到一组点值,然后高斯消元即可。

最后,我们将多项式的各项系数带入即可求出答案。

法4: 分治

定义函数 f ( n , k ) = ∑ i = 1 n i k f(n,k)=\sum_{i=1}^n i^k f(n,k)=i=1nik

如果 n n n为奇数,那么 f ( n , k ) = f ( n − 1 , k ) + n k f(n,k)=f(n-1,k)+n^k f(n,k)=f(n1,k)+nk
如果 n n n为偶数,那么 f ( n , k ) = f ( n 2 , k ) + ∑ i = 1 n 2 ( i + n 2 ) k f(n,k)=f(\frac n 2,k)+\sum_{i=1}^{\frac n 2} (i+\frac n 2)^k f(n,k)=f(2n,k)+i=12n(i+2n)k

p = n 2 p=\frac n 2 p=2n,用二项式定理拆开:

f ( p , k ) + ∑ i = 1 p ( i + p ) k f(p,k)+\sum_{i=1}^{p} (i+p)^k f(p,k)+i=1p(i+p)k
= f ( p , k ) + ∑ i = 1 p ∑ j = 0 k i j p k − j   C k j =f(p,k)+\sum_{i=1}^p \sum_{j=0}^k i^j p^{k-j}\ C_k^j =f(p,k)+i=1pj=0kijpkj Ckj
= f ( p , k ) + ∑ j = 0 k C k j   p k − j ( ∑ i = 1 p i j ) =f(p,k)+\sum_{j=0}^k C_{k}^j\ p^{k-j}(\sum_{i=1}^p i^j) =f(p,k)+j=0kCkj pkj(i=1pij)
= f ( p , k ) + ∑ j = 0 k C k j   p k − j f ( p , j ) =f(p,k)+\sum_{j=0}^k C_{k}^j\ p^{k-j} f(p,j) =f(p,k)+j=0kCkj pkjf(p,j)

于是我们直接记忆化搜索处理即可。

由于递归共有 k k k层,每一层递归了 log ⁡ k \log k logk次,且每次求和的复杂度为 k k k,所以总复杂度为 O ( k 2 log ⁡ k ) O(k^2 \log k) O(k2logk)

法5: 递推

首先,不难发现 ∑ i = 1 n ( i + 1 ) k − i k = ( n + 1 ) k − 1 \sum_{i=1}^n (i+1)^k-i^k=(n+1)^k-1 i=1n(i+1)kik=(n+1)k1

同时,也有 ∑ i = 1 n ( i + 1 ) k − i k \sum_{i=1}^n (i+1)^k-i^k i=1n(i+1)kik

= ∑ i = 1 n ( ∑ j = 0 k i j   C k j ) − i k =\sum_{i=1}^n (\sum_{j=0}^k i^j\ C_k^j)-i^k =i=1n(j=0kij Ckj)ik

= ∑ i = 1 n ( ∑ j = 0 k − 1 i j   C k j ) =\sum_{i=1}^n (\sum_{j=0}^{k-1} i^j\ C_k^j) =i=1n(j=0k1ij Ckj)

= ∑ j = 0 k − 1 ( ∑ i = 1 n i j ) C k j =\sum_{j=0}^{k-1}(\sum_{i=1}^n i^j) C_k^j =j=0k1(i=1nij)Ckj

= ∑ j = 0 k − 1 f ( n , j ) C k j =\sum_{j=0}^{k-1} f(n,j) C_k^j =j=0k1f(n,j)Ckj

所以,我们得到了 ( n + 1 ) k − 1 = ∑ j = 0 k − 1 f ( n , j )   C k j (n+1)^k-1=\sum_{j=0}^{k-1} f(n,j)\ C_k^j (n+1)k1=j=0k1f(n,j) Ckj

( n + 1 ) k − 1 = ( ∑ j = 0 k − 2 f ( n , j )   C k j ) + f ( n , k − 1 )   C k k − 1 (n+1)^k-1=(\sum_{j=0}^{k-2} f(n,j)\ C_k^j)+f(n,k-1)\ C_{k}^{k-1} (n+1)k1=(j=0k2f(n,j) Ckj)+f(n,k1) Ckk1

( n + 1 ) k − 1 = ( ∑ j = 0 k − 2 f ( n , j )   C k j ) + k f ( n , k − 1 ) (n+1)^k-1=(\sum_{j=0}^{k-2} f(n,j)\ C_k^j)+k f(n,k-1) (n+1)k1=(j=0k2f(n,j) Ckj)+kf(n,k1)

最终,我们得到了递推式

f ( n , k ) = ( n + 1 ) k + 1 − 1 − ∑ i = 0 k − 1 f ( n , i )   C k + 1 i k + 1 f(n,k)=\frac {(n+1)^{k+1}-1-\sum_{i=0}^{k-1} f(n,i)\ C_{k+1}^i} {k+1} f(n,k)=k+1(n+1)k+11i=0k1f(n,i) Ck+1i

时间复杂度为 O ( k 2 ) O(k^2) O(k2)

法6: 拉格朗日插值

首先回忆一下法 1 1 1的做法。我们求出了多项式的 k + 2 k+2 k+2个点值,然后高斯消元求出 k + 1 k+1 k+1次多项式的各项系数,最后再带入 x = n x=n x=n求出答案……

不难发现这个问题形如“给定 k + 2 k+2 k+2个点值 f ( x 1 ) , f ( x 2 ) ⋯ f ( x k + 2 ) f(x_1),f(x_2) \cdots f(x_{k+2}) f(x1),f(x2)f(xk+2),请求出 f ( n ) f(n) f(n)”。我们考虑用拉格朗日插值替代掉时间复杂度较差的高斯消元。

我们直接暴力插值,时间复杂度 O ( k 2 ) O(k^2) O(k2)的。

观察一下拉格朗日差值的式子: f ( n ) = ∑ i = 1 k + 2 y i ∏ j ≠ i n − x j x i − x j f(n)=\sum_{i=1}^{k+2} y_i \prod_{j \neq i} \frac {n-x_j} {x_i-x_j} f(n)=i=1k+2yij=ixixjnxj

不难发现,本题中带入的点值没有特殊要求,于是我们可以构造一组特殊的点值并将它们带进去来优化复杂度。傅里叶: 把单位根带进去

最优方案是带入一组 x x x连续的点值,即将 x = 1 , 2 ⋯ k + 2 x=1,2 \cdots {k+2} x=1,2k+2依次带入。此时后面的式子就变成了

∑ i = 1 k + 2 y i ∏ j ≠ i n − j i − j \sum_{i=1}^{k+2} y_i \prod_{j \neq i} \frac {n-j} {i-j} i=1k+2yij=iijnj

不难发现, ∏ j ≠ i n − j i − j \prod_{j \neq i} \frac {n-j} {i-j} j=iijnj是一个前缀积/后缀积的形式,我们可以预处理。

通过一些逆元的小 Trick 可以将时间复杂度优化到 O ( k ) O(k) O(k)

法7: 生成函数

Part 1: n 固定 , k 不固定

f k ( n ) = ∑ i = 0 n i k f_k(n)=\sum_{i=0}^n i^k fk(n)=i=0nik ,我们构造 EGF 如下:

F n ( x ) = ∑ i = 0 n S i ( n ) x i i ! F_n(x)=\sum_{i=0}^n S_i(n) \frac {x^i} {i!} Fn(x)=i=0nSi(n)i!xi

展开一波,

F k ( x ) = ∑ i = 0 n ∑ j = 1 n j i x i i ! F_k(x)=\sum_{i=0}^{n} \sum_{j=1}^n j^i \frac {x^i} {i!} Fk(x)=i=0nj=1njii!xi

F k ( x ) = ∑ j = 1 n ∑ i = 0 n j i x i i ! F_k(x)=\sum_{j=1}^{n} \sum_{i=0}^{n} j^i \frac {x^i} {i!} Fk(x)=j=1ni=0njii!xi

F k ( x ) = ∑ j = 1 n e j x F_k(x)=\sum_{j=1}^{n} e^{jx} Fk(x)=j=1nejx

不难发现右边是一个等比数列求和的形式,则

F k ( x ) = e n x − 1 1 − e − x F_k(x)=\frac {e^{nx}-1} {1-e^{-x}} Fk(x)=1exenx1

写成更加恐怖的形式:

∑ i = 0 n i n x i i !   − 1 1 − ∑ i = 0 n ( − x ) i i ! \huge {\frac {\sum_{i=0}^{n} i^n \frac {x^i} {i!} \ -1} {1-\sum_{i=0}^{n} \frac {(-x)^i} {i!}}} 1i=0ni!(x)ii=0nini!xi 1

于是,我们通过多项式求逆预处理,每次询问即可 O ( 1 ) O(1) O(1) 查询。

Part 2: n 不固定, k 固定

令第 i i i 个伯努利数为 B i B_i Bi ,其 EGF 为 F ( x ) F(x) F(x) 。直接上两个套路式:

F ( x ) = x e x e x − 1 F(x)=\frac {xe^x} {e^x-1} F(x)=ex1xex

∑ i = 1 n i k = 1 k + 1 ∑ i = 1 k + 1 C k + 1 i B k − i + 1 n i \sum_{i=1}^n i^k=\frac 1 {k+1} \sum_{i=1}^{k+1} C_{k+1}^i B_{k-i+1} n^i i=1nik=k+11i=1k+1Ck+1iBki+1ni

此时,我们直接多项式多点求值即可求出所有的答案。令询问次数为 q q q ,那么时间复杂度 O ( q log ⁡ 2 q + k log ⁡ k ) O(q \log^2 q + k \log k) O(qlog2q+klogk)

在实现的时候,多点求值递归到一个较小的区间后,直接暴力求值可以大幅减小常数。同时,注意使用较快的多项式板子,以免被毒瘤出题人卡常。

Summary

7 7 7 个方法循序渐进,时间复杂度从较差到较优,实现从容易到复杂。

在考场上,建议使用在时间复杂度正确的情况下选择最好写的做法。

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值