CF622F The Sum of the k-th Powers题解

· · 题解

写在前面的话

由于本菜鸡数学水平过差,在写这题的时候不懂为什么 \sum\limits_{i=1}^N {i^k}\text{k+1} 次多项式,在做完之后希望可以帮助到像我一样数学不好的同学,所以本文主要证明 \sum\limits_{i=1}^N {i^k}\text{k+1} 次多项式 知道的大佬们直接跳过好了

简单证明

参考资料:《数学奥林匹克竞赛小丛书(第二版) 高中卷6 -- 数列与数学归纳法》

首先看一个最基本的等差数列:

\text {1 , 2 , 3 , .. , N }

他们两两之间的差:

\text { 2 - 1 , 3 - 2 , ... , N - ( N - 1 )}$ $\Leftrightarrow$ $\text {1 , 1 , 1 , ... , 1 }

我们发现,当他们两两作差之后,得到了一个全都相同的数列,我们把它称之为常数数列

同样的,我们把广泛定义的等差数列 :

得到$\; a_2 - a_1 , a_3 - a_2 , ... \, , a_n - a_{n-1} \;$,记这个数列为$b_1 , b_2 , b_3 , .. , b_n \;$,简单记作{ ${b_n}$ } 由定义可知,他们的差也是相同的,既{ $b_n $ }是常数数列 对于一个数列 { $a_n$ } 来说,把数列 { $a_n$ } 的元素两两作差,得到数列 { $b_n$ } ,我们一般把这样的数列 { $b_n$ } 称为数列 { $a_n$ } 的**阶差数列**,记数列 { $b_n$ } 为数列 { $a_n$ } 的一阶差分,记作$\bigtriangleup f(x)=f(x+1)-f(x)

如果记该数列为 { b_n },其中 b_n = a_{n+1} - a_{n} ,再对数列 { b_n } 做差分,所得数列 \; b_2 - b_1 , b_3 - b_2 , ... \, , b_n - b_{n-1} \; 称之为原数列 { a_n } 的二阶差数列,记作\bigtriangleup^{2} f(x)

\bigtriangleup^{2} f(x)$ $=\bigtriangleup (\bigtriangleup f(x)) \qquad \quad \;$ $= \bigtriangleup(f(x+1)-f(x)) \qquad \quad \;$ $= ( f(x+2) - f(x+1) ) - ( f(x+1) - f(x) ) \qquad \quad \;$ $= f(x+2) - 2 * f(x+1) + f(x)

类似的,我们可以定义 \text {f(x)} 的二阶,三阶,..., \text {p} 阶差分

\bigtriangleup^{p} f(x) = \bigtriangleup (\bigtriangleup^{p-1} f(x) )

如果数列 { a_n } 的 \text {p} 阶差数列是一个非0常数数列,那么称它为p阶等差数列.特别地,一阶等差数列就是我们通常说的等差数列,二阶及二阶以上的等差数列统称为高阶等差数列.

定理一:

数列 { a_n } 的是一个 \text {p} 阶等差数列的充要条件是数列的通项 a_n \text {n} 的一个\text {p} 次多项式.

证明:

已知一个数列 { a_n } 的是一个 \text {p} 阶等差数列,设数列 { a_n } 的通项 a_n 是一个关于 \text {n} \text {v} 次多项式,即 f(x) = \sum\limits_{i=0}^{v}u_i*x^i,其中 u_ix^i 的系数

令数列 { b_n }成为数列 { a_n } 的一次差分,则数列 { b_n } 的通项公式为

\bigtriangleup f(x) = f(x+1) - f(x) \qquad \quad $ $= \sum\limits_{i=0}^{v}u_i*(x+1)^i - \sum\limits_{i=0}^{v}u_i*x^i

这里我们只考虑 x^v ,易知只有 [i==v] 的情况才可能得到 x^v

\qquad \quad $ $= u_v * (x+1)^v - u_v * x^v

显然 (x+1)^v 可用二项式定理拆开,但我们只考虑 x^v ,而 (x+1)^v 拆开后 x^v 的系数显然是 1

\qquad \quad $ $= u_v * x^v - u_v * x^v \qquad \quad $ $= 0

我们发现,数列 { b_n } 的通项公式中 x^v 被相减消除了,所以说,数列 { b_n } 的通项公式 b_n 是一个关于 nv-1 次多项式。也就是说,做一次差分之后数列的通项公式的多项式次数会-1

由定义可知,数列 { a_n } 的 \text {p} 阶差数列是一个非0常数数列,所以数列 { a_n } 在做 \text {p} 次差分后,得到一个 0 次多项式,即数列 { a_n } 的通项 a_n 是一个关于 n\text {p} 次多项式

证毕。

接下来回到题面上,由题意可知数列 { a_n } 为:

{\sum\limits_{i=1}^{0}i^k},{\sum\limits_{i=1}^{1}i^k},{\sum\limits_{i=1}^{2}i^k}, \; ... \; ,{\sum\limits_{i=1}^{n}i^k}

我们把他们作差得到

{\sum\limits_{i=1}^{1}i^k}-{\sum\limits_{i=1}^{0}i^k},{\sum\limits_{i=1}^{2}i^k}-{\sum\limits_{i=1}^{1}i^k}, {\sum\limits_{i=1}^{3}i^k}-{\sum\limits_{i=1}^{2}i^k}, \; ... \; ,{\sum\limits_{i=1}^{n}i^k}-{\sum\limits_{i=1}^{n-1}i^k}

1^k,2^k, ... \, ,n^k

显然的,这个数列的通项公式为 f(x) = x^k , 是一个 k 次多项式

数列 { a_n } 做一次差分后得到一个 k 次多项式,所以数列 { a_n } 的通项 a_n 是一个关于 nk+1 次多项式

到了这里,我们终于证明了 \sum\limits_{i=1}^N {i^k} 是关于 N\text{k+1} 次多项式

接下来的内容其他大佬的题解也有所说明,我这里谈谈我的做法

首先我们证明了这是一个 k+1 次多项式,但是我们没有确定其系数,于是我们考虑拉格朗日插值

由于需要 k+2 个点值才能确定 k+1 次多项式,所以我们至少要取 k+2 个点

这样一来暴力插值的复杂度为 O (k^2),显然不能做到 1e6

但是我们发现题目中有个很好的性质,就是他的点值不是确定的,而是我们可以随意选取,于是我们可以选取一些有特殊性质的点来考虑进行优化

于是我们选取一段连续的点,从 1 开始连续选取 k+2个点,那么点集为 \{ (i,\sum\limits_{j=1}^{i}j^k) | i \in [1,k+2] \}

先考虑一个点 (x,\sum\limits_{i=1}^{x}i^k)

那么 \sum\limits_{i=1}^{x}i^k = a_x * \prod\limits_{i=1,i\not=x}^{k+2}(x-i),其中 a_i 为常数

a_x = \dfrac{\sum_{i=1}^{x}i^k}{ \prod_{i=1,i\not=x}^{k+2}(x-i)}

对答案的贡献:

ans_x = a_x * \prod\limits_{i=1,i\not=x}^{k+2}(N-i) \qquad \,$ $ = \dfrac{\sum_{i=1}^{x}i^k}{ \prod_{i=1,i\not=x}^{k+2}(x-i)} * \prod\limits_{i=1,i\not=x}^{k+2}(N-i) \qquad \,$ $= \dfrac{\sum_{i=1}^{x}i^k}{ \prod_{i=1}^{x-1}(x-i) * \prod_{i=x+1}^{k+2}(x-i)} * \prod\limits_{i=1,i\not=x}^{k+2}(N-i) \qquad \,$ $= \dfrac{\sum_{i=1}^{x}i^k}{ \prod_{i=1}^{x-1}i * \prod_{i=1}^{k+2-x}(-i)} * \prod\limits_{i=1,i\not=x}^{k+2}(N-i)

显然对于 {\sum_{i=1}^{x}i^k} 来说我们可以递推+快速幂求出,对于 \prod_{i=1}^{x-1}i\prod_{i=1}^{k+2-x}(-i) 来说我们只要预处理 1k+2 的前缀积,最后再讨论

$\prod\limits_{i=1}^{k+2}(N-i) $ 再乘上 $(N-x)$ 的逆元, $O(k \,log \, k )$ 暴力求逆元或 $O(k)$ 预处理线性求逆元都可以 最后的时间复杂度其实不管怎样还会是 $O(k \,log \, k )$ 的,因为递推+快速幂求 $ {\sum_{i=1}^{x}i^k} $的时候快速幂需要 $O(log\,k)$ 的时间复杂度 由于本人码风过丑,这里就不贴出来了,其他几位大佬的 $Code$ 都写的很清晰的