題目連接:uva 766 - Sum of powers
題目大意:將Sk(n)=∑i=1nik化簡成Sk(n)=ak+1nk+1+aknk+?+a0M
解題思路:
已知冪k,並且有(n+1)k=C(kk)nk+C(k?1k)nk?1+?+C(0k)n0結論。
所以令 (n+1)k+1?nk+1=C(kk+1)nk+C(k?1k+1)nk?1+?+C(0k+1)n0
nk+1?(n?1)k+1=C(kk+1)(n?1)k+C(k?1k+1)(n?1)k?1+?+C(0k+1)(n?1)0
…
2k+1?1k+1=C(kk+1)1k+C(k?1k+1)1k?1+?+C(0k+1)10
將各項累加起來的(n+1)k?1=C(kk+1)Sk(n)+C(k?1k+1)Sk?1(n)+?+C(0k+1)S0(n)
#include
#include
typedef long long ll;
const int N = 25;
ll m[N], a[N][N];
ll C[N][N];
ll gcd (ll a, ll b) {
return b == 0 ? a : gcd(b, a%b);
}
inline ll cal (ll d) {
if (d < 0)
return -d;
return d;
}
inline ll sign (ll d) {
if (d > 0)
return 1;
else if (d < 0)
return -1;
else
return 0;
}
void del (ll& t, ll* p, int n) {
ll d = gcd(t, p[0]);
for (int i = 1; i <= n; i++) {
if (p[i] == 0)
continue;
d = gcd(d, cal(p[i]));
}
t /= d;
for (int i = 0; i <= n; i++)
p[i] = cal(p[i]) / d * sign(p[i]);
}
void add (ll* p, ll* q, ll k, ll& t, ll f, int n) {
for (int i = 0; i <= n; i++)
p[i] = p[i] * f - q[i] * k * t;
t *= f;
del(t, p, n);
}
void init () {
C[0][0] = 1;
for (int i = 1; i < N; i++) {
C[0][i] = C[i][i] = 1;
for (int j = 1; j < i; j++)
C[j][i] = C[j-1][i-1] + C[j][i-1];
}
memset(a, 0, sizeof(a));
m[0] = 1;
a[0][1] = 1;
for (int i = 1; i <= 20; i++) {
int u = i+1;
for (int j = 1; j <= u; j++)
a[i][j] += C[j][u];
m[i] = 1;
for (int j = 0; j < i; j++) {
add (a[i], a[j], C[j][u], m[i], m[j], u);
/*
for (int x = 0; x <= j + 1; x++) {
a[i][x] -= (a[j][x] * C[j][u] * tmp / m[j]);
}
*/
}
m[i] *= C[i][u];
del(m[i], a[i], u);
}
}
int main () {
init();
int cas, k;
scanf("%d", &cas);
while (cas--) {
scanf("%d", &k);
printf("%lld", m[k]);
for (int i = k+1; i >= 0; i--)
printf(" %lld", a[k][i]);
printf("\n");
if (cas)
printf("\n");
}
return 0;
}