该做法来自洛谷上的kkke,仅转载记录
*对矩阵进行优化算法 by kkke in 2015.9.12在进行矩阵运算时,[a b],发现此题中每一步b=c恒成立,且a=b+d恒成立
[c d]
于是定义新结构 [x,y] 如:A=[a1,a2], B=[b1,b2],C=[c1,c2];
并使 [x1,y1][x2,y2]=[x1x2+y1y2,x1y2+x2y1+y1y2];
即 :若 C=AB,则 c1=a1b1+a2b2 , c2=a1b2+a2b1+a2b2
易证 结构[x,y]之间的乘法满足 乘法分配率 与 乘法交换律
设数组 a[]为fibonacii数组
则可以得到 递推公式 [ a[n-1] , a[n] ] *[0,1]=[ a[n] , a[n+1] ]
而通项公式就为 [ a[n-1] , a[n] ]=[ a[1] , a[2] ]*power([0,1],n-1)
=power([0,1],n);则只需用快速幂求出[0,1]的n次方,然后拿出后一位即为a[n];
#define MOD(x_mod) ((x_mod)%1000000007 )
long long n,num_one=1;
struct fibo{
long long x,y;
fibo operator *(fibo a)
{
fibo b;
b.x=MOD(MOD(a.x*x)+MOD(a.y*y));
b.y=MOD(MOD(a.x*y)+MOD(a.y*x)+MOD(a.y*y));
return b;
}
};
fibo a,b;
void quick_power(long long k)
{
k--;
while(k)
{
if(k&num_one)b=b*a;
a=a*a;
k>>=num_one;
}
}
int main()
{
scanf("%I64d",&n);
a.x=0;a.y=1;
b.x=0;b.y=1;
quick_power(n);
printf("%I64d\n",b.y);
return 0;
}