// 列出了 n=5 时 5,4,3,2,1 出现的次数为 1 2 5 12 28
f[n+1]=3*f[n]-f[n-1]-f[n-2]-..f[1]
f[n]=3*f[n-1]-f[n-2]-..f[1]
==> f[n+1]=4*f[n]-4*f[n-1]
矩阵快速运算就可以得出答案了
// 开始提交时老错 结果是被 k>n 这种数据给坑了、、郁闷
#include <iostream>
#include <algorithm>
#include <queue>
#include <math.h>
#include <stdio.h>
#include <string.h>
using namespace std;
void deal(__int64 a[2][2],__int64 n,int m){
__int64 b[2][2],c[2][2];
int i,j;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
b[i][j]=a[i][j];
a[0][0]=1;a[0][1]=0;
a[1][0]=0;a[1][1]=1;
__int64 t=1;
for(;t<=n;t=t<<1){
if(t&n){
c[0][0]=((b[0][0]*a[0][0])%m+(b[0][1]*a[1][0])%m)%m;
c[0][1]=((b[0][0]*a[0][1])%m+(b[0][1]*a[1][1])%m)%m;
c[1][0]=((b[1][0]*a[0][0])%m+(b[1][1]*a[1][0])%m)%m;
c[1][1]=((b[1][0]*a[0][1])%m+(b[1][1]*a[1][1])%m)%m;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
a[i][j]=c[i][j];
}
c[0][0]=((b[0][0]*b[0][0])%m+(b[0][1]*b[1][0])%m)%m;
c[0][1]=((b[0][0]*b[0][1])%m+(b[0][1]*b[1][1])%m)%m;
c[1][0]=((b[1][0]*b[0][0])%m+(b[1][1]*b[1][0])%m)%m;
c[1][1]=((b[1][0]*b[0][1])%m+(b[1][1]*b[1][1])%m)%m;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
b[i][j]=c[i][j];
}
}
int main()
{
int n,k;
int num;
int MOD=1000000007;
__int64 ar[2][2];
int T;
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&k);
if(k>n) {printf("0
");continue;}
ar[0][0]=4;
ar[0][1]=-4;
ar[1][0]=1;
ar[1][1]=0;
num=n-k+1;
if(num==1){printf("1
");continue;}
if(num==2){printf("2
");continue;}
if(num==3){printf("5
");continue;}
deal(ar,num-3,MOD);
int ans=0;
ans=((ar[0][0]*5+ar[0][1]*2)%MOD+MOD)%MOD;
printf("%d
",ans);
}
return 0;
}