Sigma
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Problem Description
小H是一个程序员。他很喜欢做各种各样的数学题,尤其喜欢做《水泥数学》。
在看了《水泥数学》的2.5章后,小H终于会用9种计算 1^2+2^2+...+n^2 了!这两天,他一直在思考一个加强的问题。他想要计算1^k+...+n^k。
通过思考,他发现对所有k,P(n)=1^k+...+n^k 可以表示成一个最高次数为 k+1 的有理系数多项式。比方说当k=1时P(n)=n(n+1)/2.
现在,对某个k,小H想知道P(n)的系数。
Input
第一行为一个整数t(1 <= t <= 31),表示有 t 组测试数据;
下面T行每行一个正整数k(0 <= 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” 的形式给出,其中a和b为整数且互质,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
分析:伯努利数+组合数
#include<cstdio>
#define ll __int64
#define N 31
ll c[N][N];
struct B{
ll a,b;
}B[N];
ll gcd(ll m,ll n){return n?gcd(n,m%n):m;}
int main()
{
int T,n,i,j;
for(i=3;i<30;i+=2)B[i].a=0;
B[1].a=1,B[1].b=2;
B[2].a=1,B[2].b=6;
B[4].a=-1,B[4].b=30;
B[6].a=1,B[6].b=42;
B[8].a=-1,B[8].b=30;
B[10].a=5,B[10].b=66;
B[12].a=-691,B[12].b=2730;
B[14].a=7,B[14].b=6;
B[16].a=-3617,B[16].b=510;
B[18].a=43867,B[18].b=798;
B[20].a=-174611,B[20].b=330;
B[22].a=854513,B[22].b=138;
B[24].a=-236364091,B[24].b=2730;
B[26].a=8553103,B[26].b=6;
B[28].a=-23749461029,B[28].b=870;
B[30].a=8615841276005,B[30].b=14322;
for(i=1;i<N;i++)c[i][1]=i,c[i][i]=1,c[i][0]=1;
for(i=2;i<N;i++){
for(j=2;j<=i;j++){
c[i][j]=(c[i-1][j]+c[i-1][j-1]);
}
}
ll AA,BB,C;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
printf("1/%d",n+1);
for(i=0;i<n;i++){
AA=c[n][i]*B[i+1].a;
if(AA==0){printf(" 0/1");continue;}
BB=(i+1)*B[i+1].b;
if(AA<0)C=gcd(-AA,BB);
else C=gcd(AA,BB);
printf(" %I64d/%I64d",AA/C,BB/C);
}
puts(" 0/1");
}
return 0;
}