题面:
长期以来,LiMn2O4常常会因为自己成为不了数学选手而苦恼,并曾经有过一次转型的尝试。那是一个月黑风高的十一长假,LiMn2O4拿起了厚厚的《具体数学》。路过的practer看见了,practer说你有没有办法求一下这个公式的值:
LiMn2O4看了眼公式,说这个值有无理数,怎么表示?可以做?于是practer给了LiMn2O4第另一个公式:
求第一个公式减第二个公式的值。LiMn2O4稍加思考后觉得这个太简单了,他还要看《具体数学》,没有时间。现在交给聪明的你来解决这个问题,请你求出新的公式的第N项。
思路:
斐波那契通项公式
矩阵快速幂

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const ll p=1000000007; 5 struct node{ 6 ll a[2][2]; 7 node() 8 { 9 memset(a,0,sizeof(a)); 10 } 11 }; 12 node mul(node a,node b) 13 { 14 node s; 15 for(int i=0;i<2;i++) 16 for(int j=0;j<2;j++) 17 for(int k=0;k<2;k++) 18 s.a[i][k]=(s.a[i][k]+a.a[i][j]*b.a[j][k])%p; 19 return s; 20 } 21 node pow(node a,ll n) 22 { 23 node s; 24 for(int i=0;i<2;i++) 25 s.a[i][i]=1; 26 while(n) 27 { 28 if(n&1) 29 s=mul(s,a); 30 a=mul(a,a); 31 n>>=1; 32 } 33 return s; 34 } 35 ll n,x; 36 int main() 37 { 38 node a; 39 scanf("%lld ",&n); 40 a.a[0][0]=a.a[1][0]=a.a[0][1]=1; 41 for (int i=1;i<=n;i++) 42 { 43 scanf("%lld",&x); 44 node s=pow(a,x); 45 cout<<s.a[1][0]<<endl; 46 } 47 return 0; 48 }