题目链接:http://codeforces.com/problemset/problem/392/C
题目简述:
We'll define a new number sequence Ai(k) by the formula:
In this problem, your task is to calculate the following sum: A1(k) + A2(k) + ... + An(k). The answer can be very large, so print it modulo1000000007 (109 + 7).
(1 ≤ n ≤ 1017; 1 ≤ k ≤ 40).
Then:
=F_{i}*i^K \\
=(F_{i-1}+F_{i-2})*i^K\\
=F_{i-1}*i^K+F_{i-2}*i^K\\
=F_{i-1}*[(i-1)+1]^K+F_{i-2}*[(i-2)+2]^K\\
=\sum_{j=0}^{K} {\binom{K}{j}*F_{i-1}*(i-1)^j}+\sum_{j=0}^{K} {\binom{K}{j}*2^{K-j}*F_{i-2}*(i-2)^j}\\
=\sum_{j=0}^{K} {\binom{K}{j}*A_{i-1}(j)}+\sum_{j=0}^{K} {\binom{K}{j}*2^{K-j}*A_{i-2}(j)}\\
#include <cstdio>
#include <cstring>
#include <algorithm>
#define rep(i,l,r) for (int i=l;i<=r;++i)
#define per(i,r,l) for (int i=r;i>=l;--i)
typedef long long LL;
const LL MOD=1000000007;
const int MAX_K=45;
struct Matrix{
LL a[MAX_K*2][MAX_K*2],n,m;
Matrix(int _n = 0,int _m = 0):n(_n),m(_m){rep(i,1,n)rep(j,1,m) a[i][j]=0;}
void dw(int _n,int _m){n=_n,m=_m;rep(i,1,n)rep(j,1,m) a[i][j]=(i==j?1:0);}
LL& operator ()(int i,int j){return a[i][j];}
void print(){
rep(i,1,n) rep(j,1,m) printf("%I64d%c",a[i][j],j==m?'\n':' ');
}
};
Matrix operator *(Matrix a,Matrix b){
Matrix res(a.n,b.m);
rep(i,1,a.n) rep(j,1,b.m) rep(k,1,a.m)
(res(i,j)+=a(i,k)*b(k,j))%=MOD;
return res;
}
Matrix operator ^(Matrix a,LL x){
Matrix res;res.dw(a.n,a.m);
for (;x;a=a*a,x>>=1)
if (x&1) res=res*a;
return res;
}
LL pow2[MAX_K*2];
LL c[MAX_K*2][MAX_K*2];
void getC(int x){
c[0][0]=1;pow2[0]=1;
rep(i,1,x){
c[i][0]=1;pow2[i]=(pow2[i-1]*2)%MOD;
rep(j,1,i) c[i][j]=(c[i-1][j-1]+c[i-1][j])%MOD;
}
}
LL n,k;
int main(){
scanf("%I64d%I64d",&n,&k);
getC(k);
Matrix a(1,2*k+3),dp(2*k+3,2*k+3);
// rep(i,1,k+1) a(1,i)=1;
rep(i,1,k+1) a(1,i)=2*pow2[k-i+1];
rep(i,k+2,2*k+2) a(1,i)=1;
a(1,2*k+3)=1;
rep(i,1,k+1) rep(j,1,i) dp(i,j)=c[k-j+1][k-i+1];
rep(i,k+2,2*k+2) rep(j,1,i-(k+1))
dp(i,j)=pow2[i-(k+1)-1-(j-1)]*c[k-j+1][k-(i-(k+1))+1]%MOD;
//rep(i,1,k+1) rep(j,1,k-(i-1)+1) dp(i,j)=c[k-j+1][i-1];
//rep(i,k+2,2*k+2) rep(j,1,k-(i-(k+1)-1)+1)
// dp(i,j)=(pow2[k-(i-(k+1)-1)-(j-1)]*c[k-j+1][i-(k+1)-1])%MOD;
rep(i,k+2,2*k+2) dp(i-(k+1),i)=1;
dp(1,2*k+3)=dp(2*k+3,2*k+3)=1;
// dp.print();
// a.print();
a=a*(dp^(n-1));
// a.print();
printf("%I64d\n",a(1,2*k+3));
}
2万+



被折叠的 条评论
为什么被折叠?



