题意是求1^k+2^1+3^k+...+n^k,其中n<1e9, k<100。
利用(1+n)^k和n^i(0<=i<k)的关系构造矩阵,然后就很简单了。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <iostream>
using namespace std;
#define maxn 111
const long long mod = 1e9+7;
struct m {
long long a[maxn][maxn];
}gg;
long long n, k, c[maxn][maxn];
m danwei;
void init () {
memset (c, 0, sizeof c);
for (int i = 0; i <= 100; i++) c[i][0] = 1;
for (int i = 1; i <= 100; i++) {
for (int j = 1; j <= i; j++) {
c[i][j] = (c[i-1][j-1]+c[i-1][j])%mod;
}
}
m mul (m a, m b) {
m ans;
memset (ans.a, 0, sizeof ans.a);
for (int i = 0; i <= k+1; i++) {
for (int j = 0; j <= k+1; j++) {
for (int l = 0; l <= k+1; l++) {
ans.a[i][j] += (a.a[i][l]*b.a[l][j])%mod;
ans.a[i][j] %= mod;
}
}
}
return ans;
}
void debug (m gg) {
for (int i = 0; i <= k+1; i ++) {
for (int j = 0; j <= k+1; j++) {
cout << gg.a[i][j] << " ";
} cout << endl;
}
}
m qpow (m res, long long num) {
m ans;
ans=danwei;
for(;num;num>>=1){
if(num&1){
ans=mul(ans,res);
}
res=mul(res,res);
}
return ans;
}
int main () {
init ();
int t, kase = 0;
scanf ("%d", &t);
while (t--) {
scanf ("%lld%lld", &n, &k);
if (n == 1) {
printf ("Case%d: 1\n", ++kase);
continue;
}
memset (gg.a, 0, sizeof gg.a);
for (int i = 0; i <= k; i++) {
for (int j = i; j <= k; j++) {
gg.a[i][j] = c[j][i];
}
}
for (int i = 0; i <= k; i++)
gg.a[i][k+1] = c[k][i];
gg.a[k+1][k+1] = 1;
//debug (gg);
memset (danwei.a, 0, sizeof danwei.a);
for (int i = 0; i <= k+1; i++) {
danwei.a[i][i] = 1;
}
m fuck = qpow (gg, n-1);
//debug (fuck);
long long ans = 0;
for (int i = 0; i <= k+1; i++) {
ans += (fuck.a[i][k+1]%mod);
ans %= mod;
}
printf ("Case%d: %lld\n", ++kase, ans);
}
return 0;
}