这种题一看就想跪...数学思维不行..推不出什么东西..索性先把打表出来看看..
规律有了...实际上要求的是这么一串数列(1,2,5,12,28,64,144,320,704,1536....)的某一项...而这个数列满足F[ i ] = F[ i-1 ] *2 + 2^(i-2) ...
构造矩阵: M = 2 0 答案为 [ 5,2 ] * M^(n-k-2) 的[0][0]...
2 2
Program:
#include<iostream>
#include<stack>
#include<queue>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<cmath>
#define ll long long
#define oo 1000000007
#define MAXN 100010
using namespace std;
struct Matrix
{
ll a[2][2];
};
Matrix MatrixMul(Matrix a,Matrix b)
{
int i,j,k;
Matrix h;
memset(h.a,0,sizeof(h.a));
for (k=0;k<2;k++)
for (i=0;i<2;i++)
for (j=0;j<2;j++)
h.a[i][j]=(h.a[i][j]+(a.a[i][k]*b.a[k][j])%oo)%oo;
return h;
}
Matrix GetMarix(Matrix a,int n)
{
Matrix h,p;
int i;
h.a[0][0]=h.a[1][1]=1,h.a[0][1]=h.a[1][0]=0;
p=a;
for (i=0;i<=30;i++)
{
if (n & (1<<i)) h=MatrixMul(h,p);
p=MatrixMul(p,p);
}
return h;
}
int main()
{
int Case,n,k;
ll ans;
Matrix h;
scanf("%d",&Case);
while (Case--)
{
scanf("%d%d",&n,&k);
if (k>n) { printf("0\n"); goto A; }
if (k==n) { printf("1\n"); goto A; }
if (k==n-1){ printf("2\n"); goto A; }
h.a[0][0]=2,h.a[0][1]=0,h.a[1][0]=2,h.a[1][1]=2;
h=GetMarix(h,n-k-2);
ans=((5*h.a[0][0])%oo+h.a[1][0])%oo;
printf("%I64d\n",ans);
A: ;
}
return 0;
}