这种题一看就想跪...数学思维不行..推不出什么东西..索性先把打表出来看看..
规律有了...实际上要求的是这么一串数列(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; }