vijos1067守望者的逃离
裸的矩阵乘法,我却调了一上午……弱到爆啊……
不过最终辛苦没有白费,我终于彻底搞懂了
要注意几点:
一、必须构造出前几项
二、用矩阵乘法算法之后还要手工算答案,利用首先算好的前几项
三、想好自己构造的矩阵是横着的还是竖着的
四、要用一个单位矩阵存储最后的结果
代码:(不容易啊)
1 type matrix=array[1..15,1..15] of int64; 2 var i,n,k,j:longint; 3 ans:int64; 4 a,b:matrix; 5 f:array[0..15] of int64; 6 function mo(x:int64):int64; 7 begin 8 mo:=x mod 7777777; 9 end; 10 procedure mul(var x,y,z:matrix); 11 var i,j,l:longint; 12 t:matrix; 13 begin 14 fillchar(t,sizeof(t),0); 15 for i:=1 to k do 16 for j:=1 to k do 17 for l:=1 to k do 18 t[i,j]:=mo(t[i,j]+x[i,l]*y[l,j]); 19 z:=t; 20 end; 21 procedure ksm(times:longint); 22 begin 23 while times<>0 do 24 begin 25 if times and 1=1 then mul(a,b,b); 26 times:=times>>1; 27 mul(a,a,a); 28 end; 29 end; 30 procedure init; 31 begin 32 readln(k);readln(n); 33 fillchar(a,sizeof(a),0); 34 fillchar(b,sizeof(b),0); 35 for i:=1 to k do a[1,i]:=1; 36 for i:=2 to k do a[i,i-1]:=1; 37 for i:=1 to k do b[i,i]:=1; 38 f[0]:=1;f[1]:=1; 39 for i:=2 to k do 40 for j:=0 to i-1 do 41 f[i]:=mo(f[i]+f[j]); 42 if n<=k then begin writeln(f[n]);halt;end; 43 end; 44 procedure main; 45 begin 46 ksm(n-k); 47 ans:=0; 48 for i:=1 to k do ans:=mo(ans+b[1,i]*f[k+1-i]); 49 writeln(ans); 50 end; 51 begin 52 init; 53 main; 54 end.