Sigma问题

Problem Description
H是一个程序员。他很喜欢做各种各样的数学题,尤其喜欢做《水泥数学》。
在看了《水泥数学》的 2.5章后,小 H终于会用 9种计算 1^2+2^2+...+n^2了!这两天,他一直在思考一个加强的问题。他想要计算 1^k+...+n^k
通过思考,他发现对所有 kP(n)=1^k+...+n^k可以表示成一个最高次数为 k+1的有理系数多项式。比方说当 k=1P(n)=n(n+1)/2.
现在,对某个 k,小 H想知道 P(n)的系数。
Input
         第一行为一个整数 t1 <= t <= 31),表示有 t组测试数据;
         下面 T行每行一个正整数 k0 <= k<= 30),表示一组数据。
Output
         对于每个输入 k,输出一行 k+2个分数,依次给出此时 P(n)=a_{k+1} n^{k+1}+...+a_1 n+a_0的系数 a_{k+1}....a_0。所有分数必须以 “a/b”的形式给出,其中 ab为整数且互质, b>0;如果某一项为 0,输出 “0/1”
Sample Input
         2
         1
         2
Sample Output
         1/2 1/2 0/1
         1/3 1/2 1/6 0/1

二、           解题思路:
递推公式如下:
\sum_{i=1}^n i^{k+1}

=\sum_{i=0}^{n-1} (i+1)^{k+1}

=\sum_{i=0}^{n-1} ( \sum_{j=0}^{k+1} \binom{k+1}{j} i^j)

=\sum_{i=0}^{n-1} ( i^{k+1} + (k+1) i^k + \sum_{j=0}^{k-1} \binom{k+1}{j} i^j)

=\sum_{i=0}^{n-1} i^{k+1} + (k+1) \sum_{i=0}^{n-1} i^k + \sum_{i=0}^{n-1} ( \sum_{j=0}^{k-1} \binom{k+1}{j} i^j)

=\sum_{i=1}^{n-1} i^{k+1} + (k+1) \sum_{i=1}^{n-1} i^k + \sum_{j=0}^{k-1} \binom{k+1}{j} (\sum_{i=1}^{n-1} i^j)



so



n^{k+1} = (k+1) \sum_{i=1}^{n-1} i^k + \sum_{j=0}^{k-1} \binom{k+1}{j} (\sum_{i=1}^{n-1} i^j)

(k+1) \sum_{i=1}^{n-1} i^k = n^{k+1} + \sum_{j=0}^{k-1} \binom{k+1}{j} (\sum_{i=1}^{n-1} i^j)

(k+1) \sum_{i=1}^{n} i^k = (n+1)^{k+1} + \sum_{j=0}^{k-1} \binom{k+1}{j} (\sum_{i=1}^{n} i^j)

\sum_{i=1}^{n} i^k = ( (n+1)^{k+1} + \sum_{j=0}^{k-1} \binom{k+1}{j} (\sum_{i=1}^{n} i^j) )/ (k+1)

 
 
#include <iostream>

#include <cstdio>

using namespace std;



typedef long long LL;



const int MAXN=33;



LL C[MAXN][MAXN];

LL ca[MAXN][MAXN], cb[MAXN][MAXN];

int n;



LL gcd(LL a, LL b) {

return b==0 ? a : gcd(b,a%b);

}



void adjust(LL &a, LL &b) {

LL k=gcd(a, b);

a/=k, b/=k;

if(b<0) a=-a, b=-b;

}



void add(LL &a, LL &b, LL xa, LL xb) {

adjust(a, b); adjust(xa, xb);

LL k=gcd(b, xb);

LL u=b/k, ub=xb/k;

a*=ub; b*=ub;

xa*=u; xb*=u;

a+=xa;

adjust(a, b);

}



int main() {

int cs; for(cin>>cs; cs--; ) {

for(int i=0; i<MAXN; ++i) C[0]=C=1LL;

for(int i=1; i<MAXN; ++i) for(int j=1; j<i; ++j) C[j]=C[i-1][j-1]+C[i-1][j];

cin>>n;

ca[0][0]=0, cb[0][0]=1;

ca[0][1]=1, cb[0][1]=1;

for(int k=1; k<=n; ++k) {

for(int i=0; i<=k+1; ++i) {

ca[k]=0; cb[k]=1; } for(int i=0; i<=k+1; ++i) add(ca[k], cb[k], C[k+1], 1); for(int i=0; i<=k-1; ++i) for(int j=0; j<=i+1; ++j) add(ca[k][j], cb[k][j], -ca[j]*C[k+1], cb[j]); add(ca[k][0], cb[k][0], -1, 1); for(int i=0; i<=k+1; ++i) { cb[k]*=(LL)(k+1); adjust(ca[k], cb[k]); } } for(int i=n+1; i>=0; --i) cout<<ca[n]<<"/"<<cb[n]<<(i>0?' ':'\n'); } return 0; } 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值