关于矩阵快速幂的双倍经验。就拿Wikioi 1732做例子说好了。
做这个题之前我们首先要明白Fibonacci数列矩阵的构造,如下图:
(图片来源:http://blog.csdn.net/xuzengqiang/article/details/7645020)
那么求Fibonacci数列第N项的问题就转化成了求矩阵F的n次方的问题了。
但看到数据范围,暴力的去乘肯定会TLE,于是我们想到了快速幂(原理与数的快速幂相同)。
代码如下:
Program Wiki1732;
Const
p=1000000007;
Type
arr=array[0..2,0..2] of int64;
Var
k:int64;
Procedure matrix_multi(var a,b:arr);
var i,j,k:longint;
f:arr;
begin
fillchar(f,sizeof(f),0);
for i:=1 to 2 do
for j:=1 to 2 do
for k:=1 to 2 do
f[i,j]:=(f[i,j]+a[i,k]*b[k,j]) mod p;
for i:=1 to 2 do for j:=1 to 2 do a[i,j]:=f[i,j];
end;
Function matrix_power(k:int64):int64;
var
ans,y:arr;
begin
ans[1,1]:=1; ans[2,2]:=1; ans[1,2]:=0; ans[2,1]:=0;
y[1,1]:=1; y[1,2]:=1; y[2,1]:=1; y[2,2]:=0;
while k<>0 do
begin
if (k and 1=1) then matrix_multi(ans,y);
k:=k shr 1;
matrix_multi(y,y);
end;
exit(ans[1,2]);
end;
Begin
while not eof do
begin
readln(k);
writeln(matrix_power(k));
end;
End.