PKU 1707 Sum of powers 解题报告

本文介绍了一道关于数学公式的编程题,通过解析并转换特定的数学表达式,使用C++实现了多项式运算来求解该问题。文章详细展示了如何初始化系数矩阵、计算组合数,并最终输出结果。

具体的题目可以参看http://acm.pku.edu.cn/JudgeOnline/problem?id=1707 。题目的大意是将以下式子:

转换成以下这种形式:

要求输入        

k

要求输出

例如:

所以当输入     2

输出为              6 2 3 1 0

 

 

本文作者参照KNUTH等的《具体数学》,做了如下推导:

可以推出

所以

通过以上两个式子,我们可以推出所有k的式子的情况。 

 

以下是实现源代码(其中多项式运算比较繁琐,有看到说直接用大数进行运算来得更加方便):

 

 
#include 
<iostream>
 
using namespace std;
 
long long C(long longlong long);
void init();
long long gcd(long longlong long);
 
class Rational{

    
public:

        
long long numerator;   

        
long long denominator;

        Rational(
int num, int deno){

            numerator 
= num;

            denominator 
= deno;   

        }


        Rational()
{

            numerator 
= 0;

            denominator 
= 1;   

        }

}
;
 

Rational 
operator+ (const Rational &a, const Rational &b){

    Rational temp;

    temp.numerator 
= a.numerator * b.denominator + a.denominator * b.numerator;

    temp.denominator 
= a.denominator * b.denominator;

    
int com = gcd(temp.denominator, temp.numerator);

    temp.numerator 
/= com;

    temp.denominator 
/= com;

    
return temp;
}

 

Rational 
operator- (const Rational &a, const Rational &b){

    Rational temp;

    temp.numerator 
= a.numerator * b.denominator - a.denominator * b.numerator;

    temp.denominator 
= a.denominator * b.denominator;

    
int com = gcd(temp.denominator, temp.numerator);

    temp.numerator 
/= com;

    temp.denominator 
/= com;

    
return temp; 
}

 

Rational 
operator* (const Rational &a, const Rational &b){

    Rational temp;

    temp.numerator 
= a.numerator * b.numerator;

    temp.denominator 
= a.denominator * b.denominator;

    
int com = gcd(temp.denominator, temp.numerator);

    temp.numerator 
/= com;

    temp.denominator 
/= com;

    
return temp;   
}

 

Rational 
operator/ (const Rational &a, const Rational &b){

    Rational temp;

    temp.numerator 
= a.numerator * b.denominator;

    temp.denominator 
= a.denominator * b.numerator;

    
int com = gcd(temp.denominator, temp.numerator);

    temp.numerator 
/= com;

    temp.denominator 
/= com;

    
return temp;   
}

 
 
long long C(long long n, long long k){

    k 
= n - k < k ? (n - k) : k;

    
long long temp = 1;

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

        temp 
= temp * (n - i + 1/ i;

    }
   

    
return temp;
}

 
Rational coeff[
21][22];
int M[21];
 
void init(){

    M[
0= 1;

    coeff[
0][0].numerator = 1;

    coeff[
0][0].denominator = 1;

    coeff[
0][1].numerator = 1;

    coeff[
0][1].denominator = 1;

    
for(int i = 1; i <= 20; i++){

        
for(int j = 0; j <= i + 1; j++){       //coeff

            coeff[i][j].numerator 
= C(i + 1, j);

            coeff[i][j].denominator 
= 1;

           

            
for(int h = 0; h < i; h++){            //level

                Rational temp(C(i 
+ 1, i + 1 - h), M[h]);

                coeff[i][j] 
= coeff[i][j] - temp * coeff[h][j];

            }

                           

        }


       
 

                   
int common = 1;

                   
int denoMul = 1, numMul = 1;

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

                            coeff[i][j].denominator 
= coeff[i][j].numerator == 0 ? 1 : coeff[i][j].denominator;

                            common 
= gcd(coeff[i][j].denominator, denoMul);
                           

                            denoMul 
= coeff[i][j].denominator / common * denoMul;
                   }


                   M[i] 
= denoMul * (i + 1);

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

                            coeff[i][j].numerator 
*= denoMul / coeff[i][j].denominator;

                            coeff[i][j].denominator 
= 1;

                   }

    }
   
}

 
long long gcd(long long a, long long b){

    
if(a == 0 || b == 0)return 1;

         
if(a < 0)a = -a;

         
if(b < 0)b = -b;

    
if(a >= b)
    
{

        
if(a % b == 0)return b;

        
return gcd(b, a % b);   

    }
else {

        
if(b % a == 0)return a;

        
return gcd(a, b % a);   
    }

}

 
int main(){

    init();

    
int k;

    
while(cin >> k){

        cout 
<< M[k];

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

            cout 
<< " " << coeff[k][i].numerator;   

        }


        cout 
<< endl;
    }
   

    
return 0;
}

 
 

(p.s. 第一次在优快云写博,好累,Firefox下图片显示不出来,IE贴word中的图片显示老有问题。不过终于搞好了^_^)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值