题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6050
题意:题目很短自己看吧,
就是这个递推式子,说的很清楚了,让你求F(m,1)。题解里面分什么奇偶性分别去算,有些人找规律找出来了,题解是非常严谨的用数学推出来了(反正没有看懂),虽然也用到了矩阵快速幂。
思路:拿到这个题,我第一反应也是矩阵快速幂,然后手推了第二行,我发现第二行依旧满足上面F(2,i)=F(2,i-1)+2*F(2,i-2)这个性质。所以我就萌生一个想法,我先把一行算出来,然后把他转换成下一行。问题是如何在行与行之间转换,我们发现每一行的第一个等于上一个行1到n每一项之和,每一行的第二个,需要2到n+1每一项之和。那么我直接算出前n+1项的和Sn+1,Sn+1-Fn+1=N1,Sn+1-F1=N2。如此我们就得到了下一行的前两个。然后我们有可以同理求出再下一行。这个矩阵比较难构造,具体的矩阵是4*4的,为了说明方便,我在代码直接每一项赋值,可以把他们抄出来看看是否是这么一个回事,构造矩阵可能是一个难点,我做了挺多矩阵快速幂的题,有一些小经验,以后可能会写出来分享一下。
代码:

1 //Author: xiaowuga 2 #include <iostream> 3 #include <algorithm> 4 #include <set> 5 #include <vector> 6 #include <queue> 7 #include <cmath> 8 #include <cstring> 9 #include <cstdio> 10 #include <ctime> 11 #include <map> 12 #include <bitset> 13 #include <cctype> 14 #define maxx INT_MAX 15 #define minn INT_MIN 16 #define inf 0x3f3f3f3f 17 #define mem(s,ch) memset(s,ch,sizeof(s)) 18 #define da cout<<da<<endl 19 #define uoutput(a,i,l,r) for(int i=l;i<r;i++) if(i==l) cout<<a[i];else cout<<" "<<a[i];cout<<endl; 20 #define doutput(a,i,l,r) for(int i=r-1;i>=0;i--) if(i==r-1) cout<<a[i];else cout<<" "<<a[i];cout<<endl; 21 const long long N=4; 22 const long long mod=1e9+7; 23 using namespace std; 24 typedef long long LL; 25 struct Matrix{ 26 LL mat[N][N] = {{0}}; 27 void clear(){ 28 memset(mat,0,sizeof(mat)); 29 } 30 Matrix operator * (const Matrix & m) const{ 31 Matrix tmp; 32 for(int i=0;i<N;i++) 33 for(int k=0;k<N;k++){ 34 if (mat[i][k]) { 35 for(int j=0;j<N;j++){ 36 tmp.mat[i][j]+=mat[i][k]*m.mat[k][j]%mod; 37 tmp.mat[i][j]%=mod; 38 } 39 } 40 } 41 return tmp; 42 } 43 }; 44 Matrix POW(Matrix m,LL k){ 45 Matrix ans; 46 ans.clear(); 47 for(int i=0;i<N;i++) ans.mat[i][i]=1; 48 while(k){ 49 if(k&1) ans=ans*m; 50 k/=2; 51 m=m*m; 52 } 53 return ans; 54 } 55 Matrix xx,yy; 56 void init(){ 57 xx.mat[0][0]=1; xx.mat[0][1]=2; xx.mat[0][2]=0; xx.mat[0][3]=0; 58 xx.mat[1][0]=1; xx.mat[1][1]=0; xx.mat[1][2]=0; xx.mat[1][3]=0; 59 xx.mat[2][0]=1; xx.mat[2][1]=2; xx.mat[2][2]=1; xx.mat[2][3]=0; 60 xx.mat[3][0]=0; xx.mat[3][1]=0; xx.mat[3][2]=0; xx.mat[3][3]=1; 61 62 yy.mat[0][0]=0; yy.mat[0][1]=0; yy.mat[0][2]=1; yy.mat[0][3]=mod-1; 63 yy.mat[1][0]=mod-1; yy.mat[1][1]=0; yy.mat[1][2]=1; yy.mat[1][3]=0; 64 yy.mat[2][0]=mod-1; yy.mat[2][1]=0; yy.mat[2][2]=2; yy.mat[2][3]=mod-1; 65 yy.mat[3][0]=mod-1; yy.mat[3][1]=0; yy.mat[3][2]=1; yy.mat[3][3]=0; 66 } 67 LL n,mm; 68 int main() { 69 init(); 70 int T; 71 scanf("%lld",&T); 72 while(T--){ 73 scanf("%lld%lld",&n,&mm); 74 if(n==1||mm==1) {cout<<1<<" ";continue;} 75 Matrix ans1=POW(xx,n-1); 76 Matrix ans2=ans1*yy; 77 Matrix ans3=POW(ans2,mm); 78 LL f[4]={1,1,2,1}; 79 LL a[4]={0}; 80 for(int i=0;i<4;i++){ 81 for(int j=0;j<4;j++){ 82 a[i]+=ans3.mat[i][j]*f[j]%mod; 83 a[i]%=mod; 84 } 85 } 86 cout<<a[3]<<" "; 87 } 88 return 0; 89 }