用牛顿二项式定理转化递推式,再用矩阵快速幂求解
太菜了,看了别人的题解:https://www.cnblogs.com/simplekinght/p/6674256.html
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const ll MOD=1e9+7;
int N;
struct node
{
ll a[100][100];
};
node shu,ans,mp;
//shu是输入的矩阵,ans是所求答案
node matrix(node x,node y)
{
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++){
mp.a[i][j]=0;
for(int p=1;p<=N;p++)
mp.a[i][j]=(mp.a[i][j]+x.a[i][p]*y.a[p][j]+MOD)%MOD;
//矩阵乘法
}
return mp;
}
void work(ll k)
{//矩阵快速幂
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
ans.a[i][j]=0;
for(int i=1;i<=N;i++) ans.a[i][i]=1;
node t=shu;
while(k){
if(k&1)
ans=matrix(ans,t);
k>>=1;
t=matrix(t,t);
}
}
ll c[45][45];
void get_c(int k)
{
memset(c,0,sizeof(c));
c[0][0]=1;
for(int i=1;i<=k;i++)
{
for(int j=0;j<=i;j++)
if(j==0||j==i) c[i][j]=1;
else c[i][j]=(c[i-1][j-1]+c[i-1][j])%MOD;
}
}
void make(int k)
{
memset(shu.a,0,sizeof(shu.a));
shu.a[1][1]=1;
for(int i=0;i<=k;i++)
shu.a[1][i+2]=c[k][i];
for(int i=0;i<=k;i++)
shu.a[1][k+i+3]=c[k][i];
for(int i=0;i<=k;i++)
for(int j=0;j<=i;j++)
shu.a[i+2][j+2]=c[i][j];
for(int i=0;i<=k;i++)
for(int j=0;j<=i;j++)
shu.a[i+2][j+3+k]=c[i][j];
for(int i=0;i<=k;i++)
for(int j=0;j<=i;j++)
shu.a[i+3+k][j+2]=c[i][j];
}
ll n,k;
int main()
{
scanf("%I64d%I64d",&n,&k);
if(n==1)
{
printf("1\n");
}
else
{
N=2*k+3;
get_c(k);
make(k);
work(n-1);
ll ret=0;
for(int i=1;i<=2*k+3;i++)
ret=(ret+ans.a[1][i])%MOD;
printf("%I64d\n",ret);
}
return 0;
}