题目:
给定k,n,定义Ai = Fi + i ^ k,其中Fi为斐波拉契数列,求Ai数列的前n项和
分析:
推荐阅读:根据递推公式构造系数矩阵
容易得到递推式:
n^k 没有递推式,这样构造的系数矩阵和n有关,就不能矩阵快速幂,考虑二项式定理:
这样n^k也是递推形式的,代入上式构造如下的矩阵:
不难验证系数矩阵的正确性,可以初始化n-1 = 1 ,那么第二个矩阵全为1,矩阵中的组合数通过杨辉三角来预处理,避免溢出,剩下的就是矩阵快速幂了
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MOD = 1e9+7;
LL n,k,a[100][100],b[100][1],C[50][50];
void cal(){ //预处理组合数
for(int i = 0;i <= k; ++i){
C[i][0] = 1;
for(int j = 1;j <= i; ++j)
C[i][j] = (C[i-1][j-1] + C[i-1][j]) % MOD;
}
}
void init(){ //预处理系数矩阵和答案矩阵
cal();
for(int i = 0;i < 2*k+3; ++i) b[i][0] = 1;
a[2*k+2][2*k+2] = 1;
for(int i = 0;i < k+1; ++i)
a[2*k+2][i] = a[2*k+2][i+k+1] = C[k][i];
for(int i = 0;i < k+1; ++i)
for(int j = i; j < k+1; ++j)
a[i][j] = a[i][j+k+1] = a[i+k+1][j] = C[k-i][j-i];
}
void calmatrix1(){
LL c[100][1] = {0};
for(int i = 0;i < 2*k+3; ++i)
for(int j = 0;j < 2*k+3; ++j)
c[i][0] = (c[i][0] + a[i][j]*b[j][0]) % MOD;
memcpy(b,c,sizeof(c));
}
void calmatrix2(){
LL c[100][100] = {0};
for(int i = 0;i < 2*k+3; ++i)
for(int j = 0;j < 2*k+3; ++j)
for(int t = 0;t < 2*k+3; ++t)
c[i][t] = (c[i][t] + a[i][j]*a[j][t]) % MOD;
memcpy(a,c,sizeof(c));
}
LL solve(LL x){
init();
x -= 1;
while(x){
if(x & 1) calmatrix1();
calmatrix2();
x >>= 1;
}
return b[2*k+2][0];
}
int main()
{
cin >> n >> k;
cout << solve(n);
return 0;
}