矩阵快速幂
#include<cstdio> #include<cstring> #include<cmath> #include<map> #include<algorithm> using namespace std; const long long MOD=1000000000+7; long long n,k,RR,CC; map<long long,long long>ans; struct Matrix { long long A[5][5]; Matrix operator*(Matrix b); }; Matrix Matrix::operator*(Matrix b) { Matrix c; long long i,j,k; memset(c.A,0,sizeof(c.A)); for(i=1;i<=RR;i++) for(j=1;j<=CC;j++) for(k=1;k<=3;k++) c.A[i][j]=(c.A[i][j]+(A[i][k]*b.A[k][j]+MOD)%MOD)%MOD; return c; } int main() { ans.clear(); ans[1]=1;ans[2]=2;ans[3]=5,ans[4]=12; int T; scanf("%d",&T); while(T--) { scanf("%lld%lld",&n,&k); if(k>n) {printf("0 ");continue;} long long u=n-k+1; if(ans[u]!=0) printf("%lld ",ans[u]); else { long long i,j; long long b=u-4; Matrix JZ; JZ.A[1][1]=4;JZ.A[1][2]=0;JZ.A[1][3]=0; JZ.A[2][1]=-4;JZ.A[2][2]=4;JZ.A[2][3]=1; JZ.A[3][1]=0;JZ.A[3][2]=-4;JZ.A[3][3]=0; Matrix C; for(i=1;i<=3;i++) for(j=1;j<=3;j++) { if(i==j) C.A[i][j]=1; else C.A[i][j]=0; } RR=3;CC=3; while(b>0) { if(b%2==1)C=C*JZ,b--; else JZ=JZ*JZ,b=b/2; } RR=1;CC=3; Matrix CS; CS.A[1][1]=ans[4]; CS.A[1][2]=ans[3]; CS.A[1][3]=ans[2]; CS=CS*C; ans[u]=CS.A[1][1]; printf("%lld ",ans[u]); } } return 0; }