具体的题目可以参看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中的图片显示老有问题。不过终于搞好了^_^)