Wikioi 1250、1732 矩阵 快速幂双倍经验
以Wikioi 1732为例:
首先我们要知道Fibonacci数列矩阵的构造,如下图:

(图片来源:http://blog.csdn.net/xuzengqiang/article/details/7645020)
那么求Fibonacci数列第n项的问题就变成了求矩阵
n次方的问题了。
暴力会TLE无疑,所以我们想到了用快速幂。
1 Program Wiki1732; 2 Const 3 p=1000000007; 4 Type 5 arr=array[0..2,0..2] of int64; 6 Var 7 k:int64; 8 Procedure matrix_multi(var a,b:arr); //矩阵乘法
9 var i,j,k:longint; 10 f:arr; 11 begin 12 fillchar(f,sizeof(f),0); 13 for i:=1 to 2 do 14 for j:=1 to 2 do 15 for k:=1 to 2 do 16 f[i,j]:=(f[i,j]+a[i,k]*b[k,j]) mod p; 17 for i:=1 to 2 do for j:=1 to 2 do a[i,j]:=f[i,j]; 18 end; 19 Function matrix_power(k:int64):int64; //快速幂
20 var 21 ans,y:arr; 22 begin 23 ans[1,1]:=1; ans[2,2]:=1; ans[1,2]:=0; ans[2,1]:=0; 24 y[1,1]:=1; y[1,2]:=1; y[2,1]:=1; y[2,2]:=0; //初始化
25 while k<>0 do 26 begin 27 if (k and 1=1) then matrix_multi(ans,y); 28 k:=k shr 1; 29 matrix_multi(y,y); 30 end; 31 exit(ans[1,2]); 32 end; 33 Begin 34 while not eof do 35 begin 36 readln(k); 37 writeln(matrix_power(k)); 38 end; 39 End.
浙公网安备 33010602011771号