UVA10302 【Summation of Polynomials】
\(update:\)最后证明部分减号写成了加号,已修正,抱歉\(……\)
题目大意:设\(S(n)=1+8+27+……+x^3\),求\(S(n)\),其中\(n\leq50000\)。
显然很简单的一道题,暴力枚举,注意要开\(long\ long\)即可,代码如下。
code:
#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long
int a;
signed main() {
while (scanf("%lld", &a) == 1) {
int sum = 0;
for (int i = 1; i <= a; i++)
sum += i * i * i;
printf("%lld\n", sum);
}
return 0;
}
但题目中给了我们一种有趣的方法,我们不妨来看一下:
给定一个函数\(f(x)\),设其反差函数为\(g(x)\),且满足\(f(x)=g(x+1)-g(x)\),这样当我们对\(f(x)\)求和时,就可以像这样:
然后,定义\(k^{\{n\}}=k*(k-1)*(k-2)*……*(k-(n-1))\).
接下来,题目给出了一个重要结论,\(k^{\{n\}}\)的反差函数为\(k^{\{n+1\}}/(n+1)\).
这样,对于一个函数\(S_n=p(1)+p(2)+……+p(n)\)我们只需要找出\(p(i)\)的反差函数\(P(i)\),结果就会变为\(S_n=P(n+1)-P(1)\)。
然后题目给出了一个例子:
\(S_n=2 * 3+ 3 * 5 + 4 * 7 + ……+(n+1) * (2n+1)\),即\(p(i)=(i+1) * (2i+1)\).
接下来将\(p(i)\)表示为:
手算一下就会发现这是对的,然后根据题目中的结论求它的反差函数:
所以,\(S_n=P(n+1)-P(1)\)
将\(k^{\{n\}}\)展开我们就可以得到关于\(S_n\)的\(O(1)\)公式:
好了,以上就是题目所给的全部信息。
那么对于\(S_n=1^3+2^3+……+n^3\),显然\(p(i)=i^3\)。
接下来我们仿照例子将\(p(i)\)变换一下形式:
根据结论求反差函数:
然后将\(k^{\{n\}}\)展开,我们可以得到:
\((\)展开较为繁琐,写下来会比较乱,所以只写最终结论。\()\)
所以答案为:
显然,\(P(1)=0\)
那么
然后我们就可以\(O(1)\)来解决这个问题了,代码如下。
code:
#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long
int a;
signed main() {
while (scanf("%lld", &a) == 1) {
printf("%lld\n", (a * a * a * a + 2 * a * a * a + a * a) / 4);
}
return 0;
}
然而,我们看到例子中这一步:
你会发现这很像导数的运算法则,然而导数的运算法则是有严格证明的,所以本着严谨的态度,我们来证明一下为什么这个式子也满足这样的运算法则虽然这很显然:
对于函数\(p(i)=g(i)+h(i)\),设\(G(i)\)和\(H(i)\)分别为\(g(i)\)和\(h(i)\)的反差函数。
设函数\(P(i)=G(i)+H(i)\),那么
根据定义,我们得到\(P(i)\)即为\(p(i)\)的反差函数。
证毕。
完结撒花(✪ω✪)