PKU 1707 Sum of powers 解题报告

具体的题目可以参看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   long long   long );
void  init();
long   long  gcd( long   long long   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. 第一次在CSDN写博,好累,Firefox下图片显示不出来,IE贴word中的图片显示老有问题。不过终于搞好了^_^)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值