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.

 

posted on 2014-10-28 15:56  liqingyao  阅读(66)  评论(0)    收藏  举报

导航